home *** CD-ROM | disk | FTP | other *** search
/ Sprite 1984 - 1993 / Sprite 1984 - 1993.iso / src / X11R4 / cmds / X / os / sprite / RCS / pdev.c,v < prev    next >
Encoding:
Text File  |  1991-10-19  |  70.8 KB  |  2,791 lines

  1. head     1.13;
  2. branch   ;
  3. access   ;
  4. symbols  ;
  5. locks    ; strict;
  6. comment  @ * @;
  7.  
  8.  
  9. 1.13
  10. date     91.10.19.13.29.27;  author mendel;  state Exp;
  11. branches ;
  12. next     1.12;
  13.  
  14. 1.12
  15. date     89.06.22.09.38.41;  author ouster;  state Exp;
  16. branches ;
  17. next     1.11;
  18.  
  19. 1.11
  20. date     89.06.01.10.44.09;  author brent;  state Exp;
  21. branches ;
  22. next     1.10;
  23.  
  24. 1.10
  25. date     88.11.28.10.37.45;  author ouster;  state Exp;
  26. branches ;
  27. next     1.9;
  28.  
  29. 1.9
  30. date     88.10.01.10.55.51;  author ouster;  state Exp;
  31. branches ;
  32. next     1.8;
  33.  
  34. 1.8
  35. date     88.09.16.10.57.37;  author ouster;  state Exp;
  36. branches ;
  37. next     1.7;
  38.  
  39. 1.7
  40. date     88.09.11.13.09.20;  author ouster;  state Exp;
  41. branches ;
  42. next     1.6;
  43.  
  44. 1.6
  45. date     88.09.11.13.01.04;  author ouster;  state Exp;
  46. branches ;
  47. next     1.5;
  48.  
  49. 1.5
  50. date     88.09.09.18.00.25;  author ouster;  state Exp;
  51. branches ;
  52. next     1.4;
  53.  
  54. 1.4
  55. date     88.09.08.18.15.52;  author ouster;  state Exp;
  56. branches ;
  57. next     1.3;
  58.  
  59. 1.3
  60. date     88.08.26.16.13.09;  author brent;  state Exp;
  61. branches ;
  62. next     1.2;
  63.  
  64. 1.2
  65. date     88.08.26.08.56.51;  author deboor;  state Exp;
  66. branches ;
  67. next     1.1;
  68.  
  69. 1.1
  70. date     87.11.29.19.51.59;  author deboor;  state Exp;
  71. branches ;
  72. next     ;
  73.  
  74.  
  75. desc
  76. @Functions to support connections using the second-generation pseudo-devices
  77. @
  78.  
  79.  
  80. 1.13
  81. log
  82. @*** empty log message ***
  83. @
  84. text
  85. @/*-
  86.  * pdev.c --
  87.  *    Functions for handling a connection to a client over a pseudo-device.
  88.  *    Goal of these routine is to make a pdev connection look like a 
  89.  *    Unix domain socket.
  90.  *
  91.  *    For each client, we have two buffers -- a 2K output buffer, from
  92.  *    which the client reads, and a 2K request buffer, to which it writes.
  93.  *    The size for the output buffer is based on examination of the size
  94.  *    of buffers used in the old pseudo-device implementation. None
  95.  *    was larger than 2K, so... The input buffer size is based on the
  96.  *    size of Xlib's output buffer -- 2K. This is obviously inadequate for
  97.  *    large amounts of image data, but for most applications it should
  98.  *    be fine.
  99.  *
  100.  *
  101.  *
  102.  * Copyright (c) 1987 by the Regents of the University of California
  103.  *
  104.  * Permission to use, copy, modify, and distribute this
  105.  * software and its documentation for any purpose and without
  106.  * fee is hereby granted, provided that the above copyright
  107.  * notice appear in all copies.  The University of California
  108.  * makes no representations about the suitability of this
  109.  * software for any purpose.  It is provided "as is" without
  110.  * express or implied warranty.
  111.  *
  112.  *
  113.  */
  114. #ifndef lint
  115. static char rcsid[] =
  116. "$Header: /X11/R4/src/cmds/X/os/sprite/RCS/pdev.c,v 1.12 89/06/22 09:38:41 ouster Exp Locker: mendel $ SPRITE (Berkeley)";
  117. #endif lint
  118.  
  119. #define NEED_REPLIES /* For Debugging Only */
  120.  
  121. #define DEBUG_PDEV    0
  122. #define    DBG_PRINT    ErrorF
  123.  
  124. #define    min(a,b)    (((a) < (b)) ? (a) : (b))
  125.  
  126. #include    <fs.h>
  127. #include    <stdlib.h>
  128. #include    <dev/pdev.h>
  129. #include    <errno.h>
  130. #include    <status.h>
  131. #include    <stdio.h>
  132. #include    <sys/time.h>
  133. #include <sys/types.h>
  134. #include <sys/uio.h>
  135.  
  136. #define OUT_BUF_SIZE        2048
  137. #define IN_BUF_SIZE        2048
  138.  
  139. /*
  140.  * The private data maintained for a pseudo-device client
  141.  */
  142. typedef struct {
  143.     int                  streamID;   /* Server stream over which we get the
  144.                      * buffer pointers */
  145.     int                  state;
  146. #define    PDEV_WRITE_STALL    0x0001    /* Stall on write request. */
  147. #define PDEV_REQ_EMPTY            0x0002    /* Request buffer is empty */
  148. #define PDEV_READ_EMPTY            0x0004     /* Read buffer is empty */
  149.  
  150.     /*
  151.      * Request (inBuf) and read-ahead (outBuf) buffers
  152.      */
  153.     char            outBuf[OUT_BUF_SIZE];
  154.     char              *outPtr;    /* Next place to store data */
  155.  
  156.     char              inBuf[IN_BUF_SIZE];
  157.     Pdev_Request    *reqPtr;    /* Address of next request to process */
  158.     char              *inPtr;        /* Position in current request */
  159.     int            inSize;        /* Amount of data valid in inBuf write 
  160.                      * request. */
  161.  
  162.     Pdev_BufPtrs      curPtrs;    /* Current pointers for the two buffers */
  163.  
  164. } PdevPrivRec, *PdevPrivPtr;
  165.  
  166. #define    MAX_FD    1024
  167. static PdevPrivPtr privRecPtrs[MAX_FD];
  168. static int PdevMaster = -2;
  169.  
  170. static void PdevSetPtrs();
  171. static void PdevRequestHandled();
  172.  
  173. /*-
  174.  *-----------------------------------------------------------------------
  175.  * PdevCreate --
  176.  *    Create a pseudo-device connection MASTER.
  177.  *
  178.  * Results:
  179.  *    Open Pdev file descriptor. -1 on error. (errno set)
  180.  *
  181.  * Side Effects:
  182.  *    The pseudo-device MASTER is created are opened.
  183.  *
  184.  *-----------------------------------------------------------------------
  185.  */
  186. int
  187. PdevCreate(pathName)
  188.     char    *pathName;    /* The pathname of PDEV */
  189. {
  190.     int              pdevConn;
  191.     ReturnStatus  status;
  192.  
  193.     /*
  194.      * Create the pseudo-device, 
  195.      */
  196.  
  197.     status = Fs_Open (pathName,
  198.         FS_NON_BLOCKING | FS_CREATE | FS_READ | FS_PDEV_MASTER,
  199.         0666, &pdevConn);
  200.     if (status != 0) {
  201.     errno = Compat_MapCode(status);
  202.     DBG_PRINT (pathName);
  203.     return -1;
  204.     }
  205.     PdevMaster = pdevConn;
  206.     return pdevConn;
  207. }
  208.  
  209. /*-
  210.  *-----------------------------------------------------------------------
  211.  * PdevAccept --
  212.  *    Accept connections from new clients. 
  213.  *
  214.  * Results:
  215.  *    Stream ID of new connection -1 if error.
  216.  *
  217.  * Side Effects:
  218.  *    Memory is allocated.
  219.  *
  220.  *-----------------------------------------------------------------------
  221.  */
  222. int
  223. PdevAccept (pdevDev)
  224.     int            pdevDev;    /* Pdev master. */
  225. {
  226.     Pdev_Notify          note;            /* Notification of new stream */
  227.     PdevPrivPtr        pdevPriv;       /* New private information for us */
  228.     Pdev_Request    *pdevReq;       /* Pointer to current request */
  229.     Pdev_Reply     openReply;          /* Reply to open request */
  230.     Pdev_SetBufArgs    bufArgs;        /* Structure to set r/w buffers */
  231.     int                  numBytes;       /* Number of bytes read */
  232.     Boolean           writeBehind;    /* For IOC_PDEV_WRITE_BEHIND */
  233.     Pdev_BufPtrs      bufPtrs;    /* New buffer pointers for stream */
  234.  
  235.     writeBehind = TRUE;            /* Turn on write-behind */
  236.  
  237.     /*
  238.      * Read the connection request. 
  239.      */
  240.     numBytes = read(pdevDev, (char *) ¬e, sizeof(note));
  241.     if ((numBytes != sizeof(note)) || (note.magic != PDEV_NOTIFY_MAGIC)) {
  242.     return -1;
  243.     }
  244.     /*
  245.      * If streamID is too large ignore connection.
  246.      */
  247.     if (note.newStreamID >= MAX_FD) {
  248.     (void) close(note.newStreamID);
  249.     return -1;
  250.     }
  251.  
  252.     /*
  253.      * Allocate some memory for the private data of request.
  254.      */
  255.     pdevPriv = (PdevPrivPtr) malloc(sizeof(PdevPrivRec));
  256.     pdevPriv->streamID =                     note.newStreamID;
  257.     pdevPriv->state =                       PDEV_REQ_EMPTY|PDEV_READ_EMPTY;
  258.     pdevPriv->curPtrs.magic =               PDEV_BUF_PTR_MAGIC;
  259.     pdevPriv->curPtrs.requestFirstByte =    -1;
  260.     pdevPriv->curPtrs.requestLastByte =     -1;
  261.     pdevPriv->curPtrs.readFirstByte =       -1;
  262.     pdevPriv->curPtrs.readLastByte =        -1;
  263.     pdevPriv->inPtr =                       (char *)NULL;
  264.     pdevPriv->inSize =                       0;
  265.     pdevPriv->outPtr =                      pdevPriv->outBuf;
  266.  
  267.     bufArgs.requestBufAddr = pdevPriv->inBuf;
  268.     bufArgs.requestBufSize = IN_BUF_SIZE;
  269.     bufArgs.readBufAddr = pdevPriv->outBuf;
  270.     bufArgs.readBufSize = OUT_BUF_SIZE;
  271.  
  272.     (void)Fs_IOControl(pdevPriv->streamID, IOC_PDEV_SET_BUF,
  273.                sizeof(bufArgs), (Address)&bufArgs,
  274.                0, (Address)NULL);
  275.     (void)Fs_IOControl(pdevPriv->streamID, IOC_PDEV_WRITE_BEHIND,
  276.                sizeof(Boolean), (Address) &writeBehind,
  277.                0, (Address)NULL);
  278.     /*
  279.      * Wait for open request to come in from client.
  280.      */
  281.     numBytes = read(pdevPriv->streamID, (char *) &bufPtrs, sizeof(bufPtrs));
  282.     if (numBytes == -1) {
  283.     if (DEBUG_PDEV) {
  284.         DBG_PRINT ("PdevWaitForReadable");
  285.     }
  286.     free((char *) pdevPriv);
  287.     return (-1);
  288.     }
  289.     if (bufPtrs.magic != PDEV_BUF_PTR_MAGIC) {
  290.     if (DEBUG_PDEV) {
  291.         DBG_PRINT ("Buffer magic numbers don't match\n");
  292.     }
  293.     free((char *) pdevPriv);
  294.     return (-1);
  295.     }
  296.     PdevSetPtrs(pdevPriv, &bufPtrs);
  297.     if (pdevPriv->reqPtr->hdr.operation == PDEV_OPEN) {
  298.     pdevReq = pdevPriv->reqPtr;
  299.  
  300.     openReply.magic =       PDEV_REPLY_MAGIC;
  301.     openReply.selectBits =     FS_WRITABLE | FS_READABLE;
  302.     openReply.replySize =    0;
  303.     openReply.replyBuf =    (Address)NULL;
  304.     openReply.signal = 0;
  305.     openReply.code = 0;
  306.  
  307.     openReply.status = SUCCESS;
  308.     (void) Fs_IOControl(pdevPriv->streamID, IOC_PDEV_REPLY,
  309.                 sizeof(openReply), (Address)&openReply,
  310.                 0, (Address)NULL);
  311.     }
  312.  
  313.     PdevRequestHandled(pdevPriv);
  314.     /*
  315.      * Mark stream as non-blocking and save private data away.
  316.      */
  317.     Ioc_SetBits(pdevPriv->streamID, IOC_NON_BLOCKING); 
  318.     privRecPtrs[pdevPriv->streamID] = pdevPriv;
  319.     return pdevPriv->streamID;
  320. }
  321.     
  322. /*-
  323.  *-----------------------------------------------------------------------
  324.  * PdevClose --
  325.  *    Close down a connection.
  326.  *    XXX: Maybe we should wait for the read-ahead buffer to drain?
  327.  *
  328.  * Results:
  329.  *    -1 if error. 0 if success. errno set.
  330.  *
  331.  * Side Effects:
  332.  *    The pseudo-device stream is closed and the private data freed
  333.  *    The stream is removed from these masks:
  334.  *        AllStreamsMask, SavedAllStreamsMask, AllClientsMask,
  335.  *        SavedAllClientsMask, ClientsWithInputMask
  336.  *
  337.  *-----------------------------------------------------------------------
  338.  */
  339. int
  340. PdevClose (pdev)
  341.     int pdev;
  342. {
  343.     register PdevPrivPtr pdevPriv;
  344.  
  345.     if ((pdev < 0) || (pdev >= MAX_FD)) {
  346.     errno = EINVAL;
  347.     return -1;
  348.     }
  349.     pdevPriv = privRecPtrs[pdev];
  350.     if (pdevPriv == (PdevPrivPtr) NULL) {
  351.     errno = EINVAL;
  352.     return -1;
  353.     }
  354.  
  355.     privRecPtrs[pdev] = (PdevPrivPtr) NULL;
  356.     free((char *) pdevPriv);
  357.  
  358.     return close(pdev);
  359. }
  360.  
  361.  
  362.  
  363. /*-
  364.  *-----------------------------------------------------------------------
  365.  * PdevRead --
  366.  *    Return bytes from the given client. 
  367.  *
  368.  * Results:
  369.  *    Number of bytes read. -1 if error and errno set.
  370.  *
  371.  * Side Effects:
  372.  *
  373.  *-----------------------------------------------------------------------
  374.  */
  375. /*ARGSUSED*/
  376. int
  377. PdevRead (pdev, bufferPtr, bufLen)
  378.     int            pdev;
  379.     char        *bufferPtr;
  380.     int            bufLen;
  381. {
  382.     PdevPrivPtr      pdevPriv;   /* Private data for the client */
  383.     int                  need;        /* Number of bytes needed for the
  384.                      * current request */
  385.     Pdev_BufPtrs      bufPtrs;    /* New pointers for buffer */
  386.     int                  numBytes;
  387.     Pdev_ReplyData     reply;
  388.  
  389.     if ((pdev < 0) || (pdev >= MAX_FD)) {
  390.     errno = EINVAL;
  391.     return -1;
  392.     }
  393.     pdevPriv = privRecPtrs[pdev];
  394.     if (pdevPriv == (PdevPrivPtr) NULL) {
  395.     errno = EINVAL;
  396.     return -1;
  397.     }
  398.     numBytes = 0;
  399.     /*
  400.      * Use any data waiting from the last WRITE request. 
  401.      */
  402.     if (pdevPriv->inSize > 0) {
  403.     numBytes = min(pdevPriv->inSize, bufLen);
  404.     bcopy(pdevPriv->inPtr, bufferPtr, numBytes);
  405.     bufLen -= numBytes;
  406.     pdevPriv->inSize -= numBytes;
  407.     if (pdevPriv->inSize == 0) {
  408.         PdevRequestHandled(pdevPriv);
  409.     }
  410.     }
  411.     if (bufLen == 0) {
  412.     return numBytes;
  413.     }
  414.     if (pdevPriv->state & PDEV_REQ_EMPTY) {
  415.     int count;
  416.     /*
  417.      * If the request buffer is empty, we think, then we need to see if
  418.      * the kernel has anything for us. 
  419.      */
  420.     count = read(pdev, &bufPtrs, sizeof(bufPtrs));
  421.     if (count == -1) {
  422.         if (errno != EWOULDBLOCK) {
  423.         if (DEBUG_PDEV) {
  424.             DBG_PRINT ("Reading buffer pointers");
  425.         }
  426.         return(-1);
  427.         } 
  428.     } else if ((count != sizeof(bufPtrs)) ||
  429.         (bufPtrs.magic != PDEV_BUF_PTR_MAGIC)) {
  430.         if (DEBUG_PDEV) {
  431.             DBG_PRINT ("Improper data when reading buffer pointers");
  432.         }
  433.         return (-1);
  434.     } else {
  435.         PdevSetPtrs(pdevPriv, &bufPtrs);
  436.     }
  437.     }
  438.  
  439.     /*
  440.      * Process the requests until we run out or get enought data.
  441.      */
  442.     while (!(pdevPriv->state & PDEV_REQ_EMPTY) && (bufLen > 0)) {
  443.     switch (pdevPriv->reqPtr->hdr.operation) {
  444.         case PDEV_WRITE_ASYNC:
  445.         case PDEV_WRITE: {
  446.         int got;
  447.         if (DEBUG_PDEV) {
  448.             DBG_PRINT ("pdev %d: PDEV_WRITE(%d)\n",
  449.                pdev,
  450.                pdevPriv->reqPtr->hdr.requestSize);
  451.         }
  452.         pdevPriv->inPtr = (char *)&pdevPriv->reqPtr[1];
  453.         pdevPriv->inSize = pdevPriv->reqPtr->hdr.requestSize;
  454.         got = min(bufLen, pdevPriv->inSize);
  455.         bcopy(pdevPriv->inPtr, bufferPtr + numBytes, got);
  456.         bufLen -= got;
  457.         pdevPriv->inSize -= got;
  458.         pdevPriv->inPtr += got;
  459.         numBytes += got;
  460.         if (pdevPriv->inSize == 0) { 
  461.             PdevRequestHandled(pdevPriv);
  462.         }
  463.         break;
  464.         }
  465.         case PDEV_CLOSE:
  466.         /*
  467.          * We like closes. We just return -1 to cause the
  468.          * connection to be aborted.
  469.          */
  470.         if (DEBUG_PDEV) {
  471.             DBG_PRINT ("client %d: PDEV_CLOSE\n", pdevPriv->streamID);
  472.         }
  473.         reply.magic = PDEV_REPLY_MAGIC;
  474.         reply.status = SUCCESS;
  475.         reply.selectBits = 0;
  476.         reply.replySize = 0;
  477.         reply.replyBuf = (Address)NULL;
  478.         reply.signal = 0;
  479.         reply.code = 0;
  480.         (void)Fs_IOControl(pdevPriv->streamID,
  481.                    IOC_PDEV_REPLY,
  482.                    sizeof(reply), (Address)&reply,
  483.                    0, (Address)NULL);
  484.         PdevRequestHandled(pdevPriv);
  485.         errno = ECONNRESET;
  486.         return (-1);
  487.         case PDEV_IOCTL: {
  488.         /*
  489.          * All this should be unnecessary, but we reply to it
  490.          * anyway and pretend we know what we're doing when it
  491.          * comes to the IOC_NUM_READABLE
  492.          */
  493.         char    *inBuffer;
  494.         int    replyBuf;
  495.         int    command;
  496.         
  497.         reply.magic = PDEV_REPLY_MAGIC;
  498.         reply.status = SUCCESS;
  499.         reply.selectBits =
  500.             ((pdevPriv->state & PDEV_READ_EMPTY)?0:FS_READABLE) |
  501.             FS_WRITABLE;
  502.         reply.replySize = 0;
  503.         reply.replyBuf = (Address)&replyBuf;
  504.         
  505.         if (pdevPriv->reqPtr->hdr.requestSize) {
  506.             inBuffer = (char *)&pdevPriv->reqPtr[1];
  507.         } else {
  508.             inBuffer = (char *)NULL;
  509.         }
  510.         if (DEBUG_PDEV) {
  511.             DBG_PRINT ("pdev %d: PDEV_IOCTL(%x, %d, %x, %d, ...)\n",
  512.                pdevPriv->streamID,
  513.                pdevPriv->reqPtr->param.ioctl.command,
  514.                pdevPriv->reqPtr->hdr.requestSize,
  515.                inBuffer,
  516.                pdevPriv->reqPtr->hdr.replySize);
  517.         }
  518.         
  519.         switch (pdevPriv->reqPtr->param.ioctl.command) {
  520.             case IOC_NUM_READABLE:
  521.             /*
  522.              * XXX: This is already handled by the
  523.              * kernel since it knows how much it has
  524.              * more accurately than I do.
  525.              */
  526.             reply.replySize = sizeof(int);
  527.             replyBuf = pdevPriv->curPtrs.readLastByte -
  528.                 pdevPriv->curPtrs.readFirstByte;
  529.             break;
  530.             case IOC_SET_BITS:
  531.             case IOC_SET_FLAGS:
  532.             break;
  533.             case IOC_CLEAR_BITS:
  534.             case IOC_GET_FLAGS:
  535.             replyBuf = 0;
  536.             reply.replySize = sizeof(int);
  537.             break;
  538.             default:
  539.             if (DEBUG_PDEV) {
  540.                 DBG_PRINT ("Invalid IOCTL %x\n",
  541.                    pdevPriv->reqPtr->param.ioctl.command);
  542.             }
  543.             reply.status = FS_DEVICE_OP_INVALID;
  544.             break;
  545.         }
  546.         reply.signal = 0;
  547.         reply.code = 0;
  548.         if (reply.replySize > 0) {
  549.             *(int *)reply.data = replyBuf;
  550.             command = IOC_PDEV_SMALL_REPLY;
  551.         } else {
  552.             command = IOC_PDEV_REPLY;
  553.         }
  554.         (void)Fs_IOControl(pdevPriv->streamID,
  555.                    command,
  556.                    sizeof(reply), (Address)&reply,
  557.                    0, (Address)NULL);
  558.         PdevRequestHandled(pdevPriv);
  559.         break;
  560.         }
  561.         default:
  562.         /*
  563.          * Bad pseudo-device request -- close the beastie down
  564.          */
  565.         reply.magic = PDEV_REPLY_MAGIC;
  566.         reply.status = FS_DEVICE_OP_INVALID;
  567.         reply.selectBits = 0;
  568.         reply.replySize = 0;
  569.         reply.replyBuf = (Address)NULL;
  570.         reply.signal = 0;
  571.         reply.code = 0;
  572.         if (DEBUG_PDEV) {
  573.             DBG_PRINT ("Bad new pdev request %d pdev %d\n",
  574.                pdevPriv->reqPtr->hdr.operation,
  575.                pdevPriv->streamID);
  576.         }
  577.         (void)Fs_IOControl(pdevPriv->streamID,
  578.                    IOC_PDEV_REPLY,
  579.                    sizeof(reply), (Address)&reply,
  580.                    0, (Address)NULL);
  581.         PdevRequestHandled(pdevPriv);
  582.         errno = ECONNRESET;
  583.         return (-1);
  584.     }
  585.     }
  586.     if (numBytes == 0) {
  587.     errno = EWOULDBLOCK;
  588.     return (-1);
  589.     }
  590.     return numBytes;
  591. }
  592.  
  593. /*-
  594.  *-----------------------------------------------------------------------
  595.  * PdevWritev --
  596.  *    Write data to the client. Data are copied into the read buffer
  597.  *    as much as possible. 
  598.  *
  599.  * Results:
  600.  *    Number of bytes written.
  601.  *
  602.  * Side Effects:
  603.  *    The data bytes are stuffed into the buffer for the client, awaiting
  604.  *    a read request from the client.
  605.  *
  606.  *-----------------------------------------------------------------------
  607.  */
  608. int
  609. PdevWritev(pdev, iov, iovcnt)
  610.     int        pdev;
  611.     struct iovec *iov;
  612.     int iovcnt;
  613. {
  614.     register PdevPrivPtr    pdevPriv;        /* Data private to client */
  615.     ReturnStatus        status;
  616.     int       numWrite, numWritten, i;
  617.  
  618.  
  619.     if ((pdev < 0) || (pdev >= MAX_FD)) {
  620.     errno = EINVAL;
  621.     return -1;
  622.     }
  623.     pdevPriv = privRecPtrs[pdev];
  624.     if (pdevPriv == (PdevPrivPtr) NULL) {
  625.     errno = EINVAL;
  626.     return -1;
  627.     }
  628.  
  629.     if (pdevPriv->curPtrs.readLastByte >= (OUT_BUF_SIZE - 1)) {
  630.     pdevPriv->state |= PDEV_WRITE_STALL;
  631.     errno = EWOULDBLOCK;
  632.     return -1;
  633.     }
  634.     pdevPriv->state &= ~PDEV_WRITE_STALL;
  635.  
  636.     numWritten = 0;
  637.     for (i = 0; (i < iovcnt) && 
  638.         (pdevPriv->curPtrs.readLastByte < (OUT_BUF_SIZE - 1)); i++) {
  639.     int spaceAvailable;
  640.  
  641.     spaceAvailable = (pdevPriv->curPtrs.readLastByte == -1) ? OUT_BUF_SIZE 
  642.                 : (OUT_BUF_SIZE - pdevPriv->curPtrs.readLastByte);
  643.  
  644.     numWrite = min(iov[i].iov_len, spaceAvailable);
  645.     bcopy((char *) iov[i].iov_base, (char *) pdevPriv->outPtr, numWrite);
  646.  
  647.     /*
  648.      * Update the output pointers. Note that since readLastByte starts
  649.      * at -1, adding numWrite will point to the last valid byte of data
  650.      * in the buffer...
  651.      */
  652.     pdevPriv->curPtrs.readLastByte += numWrite;
  653.     pdevPriv->outPtr += numWrite;
  654.     numWritten += numWrite;
  655.     }
  656.  
  657.  
  658.     /*
  659.      * Inform kernel of new read buffer extents
  660.      */
  661.     status = Fs_IOControl(pdevPriv->streamID, IOC_PDEV_SET_PTRS,
  662.         sizeof(pdevPriv->curPtrs), (Address) &pdevPriv->curPtrs,
  663.         0, (Address) NULL);
  664.     if (status != 0) {
  665.     errno = Compat_MapCode(status);
  666.     if (DEBUG_PDEV) {
  667.         DBG_PRINT ("WriteClient: SET_PTRS");
  668.     }
  669.     return -1;
  670.     }
  671.     return (numWritten);
  672. }
  673.  
  674. /*-
  675.  *-----------------------------------------------------------------------
  676.  * PdevWrite --
  677.  *    Write data to the client. Data are copied into the read buffer
  678.  *    as much as possible. 
  679.  *
  680.  * Results:
  681.  *    Number of bytes written.
  682.  *
  683.  * Side Effects:
  684.  *    The data bytes are stuffed into the buffer for the client, awaiting
  685.  *    a read request from the client.
  686.  *
  687.  *-----------------------------------------------------------------------
  688.  */
  689. int
  690. PdevWrite(pdev, buf, nbytes)
  691.     int        pdev;
  692.     char *buf;
  693.     int    nbytes;
  694. {
  695.     struct iovec io;
  696.     io.iov_base = buf;
  697.     io.iov_len = nbytes;
  698.     return PdevWritev(pdev, &io, 1);
  699. }
  700.  
  701. int 
  702. PdevIsMaster(pdev)
  703.     int    pdev;
  704. {
  705.     return (pdev == PdevMaster);
  706. }
  707. int
  708. PdevIsPdevConn(pdev) 
  709. {
  710.     return ((pdev >= 0) && (pdev <= MAX_FD) && privRecPtrs[pdev]);
  711. }
  712.  
  713. /*-
  714.  *-----------------------------------------------------------------------
  715.  * PdevSetPtrs --
  716.  *    Set our idea of the state of the two buffers. Called when a
  717.  *    Pdev_BufPtrs structure is read from the kernel. If the read-ahead
  718.  *    buffer has been emptied by the kernel and there's overflow waiting
  719.  *    to go, copy it down and inform the kernel of it.
  720.  *
  721.  * Results:
  722.  *    None.
  723.  *
  724.  * Side Effects:
  725.  *    curPtrs is altered.
  726.  *
  727.  *-----------------------------------------------------------------------
  728.  */
  729. static void
  730. PdevSetPtrs(pdevPriv, bufPtrs)
  731.     PdevPrivPtr    pdevPriv;
  732.     Pdev_BufPtrs      *bufPtrs;
  733. {
  734.     if (DEBUG_PDEV) {
  735.     DBG_PRINT ("SetPtrs(%d): req %d:%d read %d:%d\n",
  736.            pdevPriv->streamID,
  737.            bufPtrs->requestFirstByte,
  738.            bufPtrs->requestLastByte,
  739.            bufPtrs->readFirstByte,
  740.            bufPtrs->readLastByte);
  741.     }
  742.  
  743.     /*
  744.      * First update the extent of the request buffer.
  745.      */
  746.     pdevPriv->curPtrs.requestLastByte = bufPtrs->requestLastByte;
  747.     if ((bufPtrs->requestLastByte != -1)  &&
  748.     (pdevPriv->state & PDEV_REQ_EMPTY)) {
  749.         /*
  750.          * We only pay attention to the requestFirstByte if going from
  751.          * an empty to a non-empty buffer, since we think we know where
  752.          * the first request byte actually is.
  753.          */
  754.         pdevPriv->curPtrs.requestFirstByte = bufPtrs->requestFirstByte;
  755.         pdevPriv->reqPtr =
  756.         (Pdev_Request *)&pdevPriv->inBuf[bufPtrs->requestFirstByte];
  757.         pdevPriv->inSize = 0;
  758.         pdevPriv->state &= ~PDEV_REQ_EMPTY;
  759.     }
  760.  
  761.     /*
  762.      * Then the extent of the read buffer.
  763.      */
  764.     pdevPriv->curPtrs.readFirstByte = bufPtrs->readFirstByte;
  765.     if (bufPtrs->readFirstByte == -1) {
  766.     int   numBytes;
  767.  
  768.     pdevPriv->state |= PDEV_READ_EMPTY;
  769.     pdevPriv->outPtr = pdevPriv->outBuf;
  770.  
  771.     /*
  772.      * Need to make this -1 so PdevWriteClient works correctly
  773.      * (it adds the number of bytes written to readLastByte without
  774.      * checking its value)
  775.      */
  776.     pdevPriv->curPtrs.readLastByte = -1;
  777.     }
  778. /*
  779.  * This is needed until select() on a pdev returns when it is writable.
  780.  */
  781.     if ((pdevPriv->state & PDEV_WRITE_STALL) && 
  782.     (pdevPriv->curPtrs.readLastByte < (OUT_BUF_SIZE - 1))) {
  783.     PdevClearWriteBlockHack(pdevPriv->streamID);
  784.     }
  785. }
  786.     
  787. /*-
  788.  *-----------------------------------------------------------------------
  789.  * PdevRequestHandled --
  790.  *    Tell the kernel that we have handled the request at
  791.  *    pdevPriv->reqPtr and update our own idea of the request buffer.
  792.  *
  793.  * Results:
  794.  *    None.
  795.  *
  796.  * Side Effects:
  797.  *    curPtrs.requestFirstByte is altered, inPtr is NULLed, the
  798.  *    PDEV_REQ_EMPTY flag will be set if the buffer is now empty.
  799.  *
  800.  *-----------------------------------------------------------------------
  801.  */
  802. static void
  803. PdevRequestHandled(pdevPriv)
  804.     PdevPrivPtr    pdevPriv;
  805. {
  806.     ReturnStatus status;
  807.  
  808.     pdevPriv->inPtr = (char *)NULL;
  809.     pdevPriv->inSize = 0;
  810.     pdevPriv->curPtrs.requestFirstByte += pdevPriv->reqPtr->hdr.messageSize;
  811.     pdevPriv->reqPtr =
  812.     (Pdev_Request *)&pdevPriv->inBuf[pdevPriv->curPtrs.requestFirstByte];
  813.  
  814.     if (pdevPriv->curPtrs.requestFirstByte >
  815.     pdevPriv->curPtrs.requestLastByte) {
  816.         pdevPriv->state |= PDEV_REQ_EMPTY;
  817.     }
  818.  
  819.     if (DEBUG_PDEV) {
  820.     DBG_PRINT ("RequestHandled(%d): req %d:%d read %d:%d\n",
  821.            pdevPriv->streamID, 
  822.            pdevPriv->curPtrs.requestFirstByte,
  823.            pdevPriv->curPtrs.requestLastByte,
  824.            pdevPriv->curPtrs.readFirstByte,
  825.            pdevPriv->curPtrs.readLastByte);
  826.     }
  827.  
  828.     status = Fs_IOControl(pdevPriv->streamID, IOC_PDEV_SET_PTRS,
  829.         sizeof(pdevPriv->curPtrs), (Address) &pdevPriv->curPtrs,
  830.         0, (Address) NULL);
  831.     if (status != 0) {
  832.     errno = Compat_MapCode(status);
  833.     if (DEBUG_PDEV) {
  834.         DBG_PRINT ("RequestHandled: SET_PTRS");
  835.     }
  836.     }
  837.     if (pdevPriv->state & PDEV_REQ_EMPTY) {
  838.     pdevPriv->curPtrs.requestFirstByte =
  839.         pdevPriv->curPtrs.requestLastByte = -1;
  840.     }
  841. }
  842.  
  843. @
  844.  
  845.  
  846. 1.12
  847. log
  848. @Changes for new pdev code (large vs. small replies, signal returns).
  849. @
  850. text
  851. @d4 2
  852. a15 7
  853.  *    Requests are processed from the request buffer in order, obviously,
  854.  *    with a write request remaining current until all its data have been
  855.  *    consumed. If an X request crosses a pdev request boundary, it is
  856.  *    copied and collected in a separate area, which is deallocated on the
  857.  *    next call. X requests wholy inside a pdev request are left in the
  858.  *    buffer. The kernel is not told the pdev request has been processed
  859.  *    until all X requests in the pdev request have been handled.
  860. a16 3
  861.  *    Each time data are written to the read buffer, the pointers are
  862.  *    updated. The stream is not read until the request buffer has
  863.  *    been exhausted.
  864. d32 1
  865. a32 1
  866. "$Header: /a/X/src/cmds/Xsprite/os/RCS/pdev.c,v 1.11 89/06/01 10:44:09 brent Exp Locker: brent $ SPRITE (Berkeley)";
  867. d37 4
  868. a40 4
  869. /*
  870.  * These first two header files must indeed be first, or else this
  871.  * file won't compile.
  872.  */
  873. a41 1
  874. #define Time SpriteTime
  875. a42 1
  876. #undef Time
  877. a43 7
  878.  
  879. #include    "spriteos.h"
  880.  
  881. #include    "Xproto.h"
  882. #include    "opaque.h"
  883.  
  884. #include    <bit.h>
  885. d49 2
  886. a50 7
  887.  
  888. /*
  889.  * Template for the pseudo-device through which we communicate. Given to
  890.  * one of the printf functions and expects two arguments: the name of the
  891.  * local host and the display number we're using.
  892.  */
  893. #define    DEVICE_TEMPLATE    "/hosts/%s/X%s"
  894. a51 1
  895. #define REASONABLE_TIME        5
  896. a60 1
  897.     ClientPtr          client;        /* Client for which this is */
  898. d62 1
  899. a64 2
  900. #define PDEV_COLLECTING            0x0008    /* Collecting broken X request */
  901. #define PDEV_COLLECTING_HEADER    0x0010    /* Collecting broken X header */
  902. d75 2
  903. a79 15
  904.     /*
  905.      * Overflow. If the outBuf fills up, we copy the output data into
  906.      * 'overflow' and copy as much down as possible when the kernel has
  907.      * emptied outBuf.
  908.      *
  909.      * If an X request comes in that is broken across two PDEV_WRITE requests,
  910.      * we allocate enough room to hold it and point bigReq at it, then copy
  911.      * data from inBuf, as it becomes available, into bigReq until the
  912.      * request is fulfilled.
  913.      */
  914.     Buffer            overflow;   /* Any output that won't fit in outBuf */
  915.     char              *bigReq;    /* Points to space for any broken request
  916.                      * that is being assembled. NULL if none */
  917.     char              *bigReqPtr; /* Current position in bigReq */
  918.     int                  need;        /* Number of bytes still needed */
  919. d82 3
  920. a84 3
  921. static void       PdevCloseClient();
  922. static char       *PdevReadClient();
  923. static int        PdevWriteClient();
  924. d86 19
  925. a104 19
  926. int              Pdev_Conn;
  927.  
  928. /*-
  929.  *-----------------------------------------------------------------------
  930.  * Pdev_Init --
  931.  *    Initialize pseudo-device connections.
  932.  *
  933.  * Results:
  934.  *    None.
  935.  *
  936.  * Side Effects:
  937.  *    The pseudo-device for this display is opened. The process will
  938.  *    exit if the device cannot be opened.
  939.  *
  940.  *-----------------------------------------------------------------------
  941.  */
  942. void
  943. Pdev_Init(hostname)
  944.     char    *hostname;    /* The name of the local host */
  945. d106 1
  946. a106 2
  947.     char          deviceName[100];  /* Path to pseudo-device */
  948.     int              oldPermMask;        /* Previous permission mask */
  949. d110 1
  950. a110 2
  951.      * Create the pseudo-device, making sure it's readable and writable
  952.      * by everyone.
  953. d113 1
  954. a113 3
  955.     sprintf (deviceName, DEVICE_TEMPLATE, hostname, display);
  956.     oldPermMask = umask(0);
  957.     status = Fs_Open (deviceName,
  958. d115 1
  959. a115 1
  960.         0666, &Pdev_Conn);
  961. d118 2
  962. a119 3
  963.     Error (deviceName);
  964.     FatalError ("Could not open pseudo-device %s",
  965.         deviceName);
  966. d121 2
  967. a122 2
  968.  
  969.     (void) umask(oldPermMask);
  970. d127 2
  971. a128 5
  972.  * PdevSetPtrs --
  973.  *    Set our idea of the state of the two buffers. Called when a
  974.  *    Pdev_BufPtrs structure is read from the kernel. If the read-ahead
  975.  *    buffer has been emptied by the kernel and there's overflow waiting
  976.  *    to go, copy it down and inform the kernel of it.
  977. d131 1
  978. a131 1
  979.  *    None.
  980. d134 1
  981. a134 1
  982.  *    curPtrs is altered.
  983. d136 1
  984. a136 1
  985.  *-----------------------------------------------------------------------
  986. d138 3
  987. a140 4
  988. static void
  989. PdevSetPtrs(pdevPriv, bufPtrs)
  990.     PdevPrivPtr    pdevPriv;
  991.     Pdev_BufPtrs      *bufPtrs;
  992. d142 10
  993. a151 8
  994.     if (DBG(PDEV)) {
  995.     ErrorF("SetPtrs(%d): req %d:%d read %d:%d\n",
  996.            pdevPriv->client ? pdevPriv->client->index : -1,
  997.            bufPtrs->requestFirstByte,
  998.            bufPtrs->requestLastByte,
  999.            bufPtrs->readFirstByte,
  1000.            bufPtrs->readLastByte);
  1001.     }
  1002. d154 1
  1003. a154 1
  1004.      * First update the extent of the request buffer.
  1005. d156 3
  1006. a158 13
  1007.     pdevPriv->curPtrs.requestLastByte = bufPtrs->requestLastByte;
  1008.     if ((bufPtrs->requestLastByte != -1)  &&
  1009.     (pdevPriv->state & PDEV_REQ_EMPTY)) {
  1010.         /*
  1011.          * We only pay attention to the requestFirstByte if going from
  1012.          * an empty to a non-empty buffer, since we think we know where
  1013.          * the first request byte actually is.
  1014.          */
  1015.         pdevPriv->curPtrs.requestFirstByte = bufPtrs->requestFirstByte;
  1016.         pdevPriv->reqPtr =
  1017.         (Pdev_Request *)&pdevPriv->inBuf[bufPtrs->requestFirstByte];
  1018.         pdevPriv->inPtr = (char *)NULL;
  1019.         pdevPriv->state &= ~PDEV_REQ_EMPTY;
  1020. a159 1
  1021.  
  1022. d161 1
  1023. a161 1
  1024.      * Then the extent of the read buffer.
  1025. d163 2
  1026. a164 136
  1027.     pdevPriv->curPtrs.readFirstByte = bufPtrs->readFirstByte;
  1028.     if (bufPtrs->readFirstByte == -1) {
  1029.     int   numBytes;
  1030.  
  1031.     pdevPriv->state |= PDEV_READ_EMPTY;
  1032.     pdevPriv->outPtr = pdevPriv->outBuf;
  1033.  
  1034.     numBytes = Buf_Size(pdevPriv->overflow);
  1035.     if (numBytes > OUT_BUF_SIZE) {
  1036.         numBytes = OUT_BUF_SIZE;
  1037.     }
  1038.     if (numBytes != 0) {
  1039.         /*
  1040.          * Copy as much overflow data into the output buffer as possible.
  1041.          * The number of bytes actually copied is left in numBytes.
  1042.          * pdevPriv->outPtr is set to point to the next place to store
  1043.          * data in the buffer.
  1044.          */
  1045.         numBytes = Buf_GetBytes(pdevPriv->overflow, numBytes,
  1046.                     (Byte *)pdevPriv->outBuf);
  1047.         pdevPriv->outPtr = &pdevPriv->outBuf[numBytes];
  1048.  
  1049.         if (numBytes != 0) {
  1050.         /*
  1051.          * If bytes actually copied, the buffer is no longer empty.
  1052.          * Adjust the pointers and inform the kernel of the existence
  1053.          * of the data.
  1054.          */
  1055.         pdevPriv->state &= ~PDEV_READ_EMPTY;
  1056.         pdevPriv->curPtrs.readFirstByte = 0;
  1057.         pdevPriv->curPtrs.readLastByte = numBytes - 1;
  1058.         (void)Fs_IOControl (pdevPriv->streamID,
  1059.                     IOC_PDEV_SET_PTRS,
  1060.                     sizeof(pdevPriv->curPtrs),
  1061.                     (Address)&pdevPriv->curPtrs,
  1062.                     0,
  1063.                     (Address)NULL);
  1064.         }
  1065.     } else {
  1066.         /*
  1067.          * Need to make this -1 so PdevWriteClient works correctly
  1068.          * (it adds the number of bytes written to readLastByte without
  1069.          * checking its value)
  1070.          */
  1071.         pdevPriv->curPtrs.readLastByte = -1;
  1072.     }
  1073.     }
  1074. }
  1075.     
  1076. /*-
  1077.  *-----------------------------------------------------------------------
  1078.  * PdevRequestHandled --
  1079.  *    Tell the kernel that we have handled the request at
  1080.  *    pdevPriv->reqPtr and update our own idea of the request buffer.
  1081.  *
  1082.  * Results:
  1083.  *    None.
  1084.  *
  1085.  * Side Effects:
  1086.  *    curPtrs.requestFirstByte is altered, inPtr is NULLed, the
  1087.  *    PDEV_REQ_EMPTY flag will be set if the buffer is now empty.
  1088.  *
  1089.  *-----------------------------------------------------------------------
  1090.  */
  1091. static void
  1092. PdevRequestHandled(pdevPriv)
  1093.     PdevPrivPtr    pdevPriv;
  1094. {
  1095.     ReturnStatus status;
  1096.  
  1097.     pdevPriv->inPtr = (char *)NULL;
  1098.     pdevPriv->curPtrs.requestFirstByte += pdevPriv->reqPtr->hdr.messageSize;
  1099.     pdevPriv->reqPtr =
  1100.     (Pdev_Request *)&pdevPriv->inBuf[pdevPriv->curPtrs.requestFirstByte];
  1101.  
  1102.     if (pdevPriv->curPtrs.requestFirstByte >
  1103.     pdevPriv->curPtrs.requestLastByte) {
  1104.         pdevPriv->state |= PDEV_REQ_EMPTY;
  1105.     }
  1106.  
  1107.     if (DBG(PDEV)) {
  1108.     ErrorF("RequestHandled(%d): req %d:%d read %d:%d\n",
  1109.            pdevPriv->client ? pdevPriv->client->index : -1,
  1110.            pdevPriv->curPtrs.requestFirstByte,
  1111.            pdevPriv->curPtrs.requestLastByte,
  1112.            pdevPriv->curPtrs.readFirstByte,
  1113.            pdevPriv->curPtrs.readLastByte);
  1114.     }
  1115.  
  1116.     status = Fs_IOControl(pdevPriv->streamID, IOC_PDEV_SET_PTRS,
  1117.         sizeof(pdevPriv->curPtrs), (Address) &pdevPriv->curPtrs,
  1118.         0, (Address) NULL);
  1119.     if (status != 0) {
  1120.     errno = Compat_MapCode(status);
  1121.     if (DBG(PDEV)) {
  1122.         Error("RequestHandled: SET_PTRS");
  1123.     }
  1124.     }
  1125.     if (pdevPriv->state & PDEV_REQ_EMPTY) {
  1126.     pdevPriv->curPtrs.requestFirstByte =
  1127.         pdevPriv->curPtrs.requestLastByte = -1;
  1128.     }
  1129. }
  1130.  
  1131. /*-
  1132.  *-----------------------------------------------------------------------
  1133.  * PdevWaitForReadable --
  1134.  *    Wait for a connection to become readable, but only wait a
  1135.  *    reasonable amount of time.
  1136.  *
  1137.  * Results:
  1138.  *    Returns 0 if successful, -1 if an error occurs or no
  1139.  *    files were readable.
  1140.  *
  1141.  * Side Effects:
  1142.  *    The curPtrs field of the connection is updated.
  1143.  *
  1144.  *-----------------------------------------------------------------------
  1145.  */
  1146. static ReturnStatus
  1147. PdevWaitForReadable (pdevPriv, selMask)
  1148.     PdevPrivPtr    pdevPriv;   /* Connection to read */
  1149.     int                  *selMask;   /* Pre-allocated select mask (zeroed) */
  1150. {
  1151.     Pdev_BufPtrs      bufPtrs;    /* New buffer pointers for stream */
  1152.     struct timeval      timeout;    /* Timeout interval for select */
  1153.     int                  numReady;   /* Number of ready streams */
  1154.     int                  numBytes;   /* Number of bytes read */
  1155.     
  1156.     Bit_Set (pdevPriv->streamID, selMask);
  1157.     timeout.tv_sec = REASONABLE_TIME;
  1158.     timeout.tv_usec = 0;
  1159.  
  1160.     numReady = select(pdevPriv->streamID+1, selMask, (int *) 0, (int *)0,
  1161.         &timeout);
  1162.     if (numReady < 1) {
  1163. d168 29
  1164. d199 2
  1165. a200 2
  1166.     if (DBG(PDEV)) {
  1167.         Error ("PdevWaitForReadable");
  1168. d202 1
  1169. d206 2
  1170. a207 2
  1171.     if (DBG(PDEV)) {
  1172.         ErrorF ("Buffer magic numbers don't match\n");
  1173. d209 1
  1174. d213 1
  1175. a213 233
  1176.     return (0);
  1177. }
  1178.  
  1179. /*-
  1180.  *-----------------------------------------------------------------------
  1181.  * PdevConnFail --
  1182.  *    Inform a client that it has been denied access.
  1183.  *
  1184.  * Results:
  1185.  *    None.
  1186.  *
  1187.  * Side Effects:
  1188.  *    None.
  1189.  *
  1190.  *-----------------------------------------------------------------------
  1191.  */
  1192. static void
  1193. PdevConnFail (pdevPriv, swapped, reason)
  1194.     PdevPrivPtr    pdevPriv;       /* Failed connection */
  1195.     Bool              swapped;        /* TRUE if client is byte-swapped */
  1196.     char              *reason;        /* Reason for failure */
  1197. {
  1198.     int                  *selMask;       /* Mask for selecting on stream */
  1199.     struct timeval      timeout;        /* Timeout for select */
  1200.     struct timeval      *pTimeOut;
  1201.     int                  numReady;       /* Number of streams from select*/
  1202.     int                  numBytes;       /* Number of bytes read/written */
  1203.     int                  length;            /* Length of reason */
  1204.     xConnSetupPrefix    *c;             /* Pointer to returned structure in
  1205.                      * read-ahead buffer */
  1206.     Pdev_BufPtrs      bufPtrs;        /* New pointers for buffer */
  1207.  
  1208.  
  1209.     if (reason == (char *)NULL) {
  1210.     length = 0;
  1211.     } else {
  1212.     length = strlen (reason);
  1213.     }
  1214.  
  1215.     c = (xConnSetupPrefix *)pdevPriv->outBuf;
  1216.     c->success = xFalse;
  1217.     c->lengthReason = length;
  1218.     c->length = (length + 3) >> 2;
  1219.  
  1220.     pdevPriv->curPtrs.readFirstByte = 0;
  1221.     pdevPriv->curPtrs.readLastByte =
  1222.     sizeof(xConnSetupPrefix) + (c->length << 2);
  1223.  
  1224.     if (!swapped) {
  1225.     c->majorVersion = X_PROTOCOL;
  1226.     c->minorVersion = X_PROTOCOL_REVISION;
  1227.     } else {
  1228.     short      n;
  1229.  
  1230.     swaps(&c->length, n);
  1231.     c->majorVersion = lswaps(X_PROTOCOL);
  1232.     c->minorVersion = lswaps(X_PROTOCOL_REVISION);
  1233.     }
  1234.     
  1235.     strcpy((char *)&c[1], reason);
  1236.  
  1237.     if (Fs_IOControl(pdevPriv->streamID, IOC_PDEV_SET_PTRS,
  1238.              sizeof(pdevPriv->curPtrs),
  1239.              (Address)&pdevPriv->curPtrs,
  1240.              0, (Address)NULL) != 0) {
  1241.              return;
  1242.     }
  1243.     
  1244.     Bit_Alloc (pdevPriv->streamID+1, selMask);
  1245.  
  1246.     timeout.tv_sec = REASONABLE_TIME;
  1247.     timeout.tv_usec = 0;
  1248.     if (DBG(PDEV)) {
  1249.     pTimeOut = (struct timeval *)0;
  1250.     } else {
  1251.     pTimeOut = &timeout;
  1252.     }
  1253.     
  1254.     /*
  1255.      * We give the client a REASONABLE_TIME to read the failure structure
  1256.      * and message. If it doesn't read it in that time, it loses. When the
  1257.      * read-ahead buffer is empty, the client has read the info.
  1258.      */
  1259.     do {
  1260.     Bit_Set (pdevPriv->streamID, selMask);
  1261.     numReady = select(pdevPriv->streamID+1, selMask, (int *)0, (int *)0,
  1262.         pTimeOut);
  1263.     if (numReady < 1) {
  1264.         if (DBG(PDEV)) {
  1265.         ErrorF("PdevConnFail: didn't read in reasonable time\n");
  1266.         }
  1267.         break;
  1268.     }
  1269.     numBytes = read(pdevPriv->streamID, (char *) &bufPtrs,
  1270.         sizeof(bufPtrs));
  1271.     if ((numBytes != sizeof(bufPtrs))
  1272.         || (bufPtrs.magic != PDEV_BUF_PTR_MAGIC)) {
  1273.         break;
  1274.     }
  1275.     if (bufPtrs.readFirstByte == -1) {
  1276.         break;
  1277.     } else {
  1278.         PdevSetPtrs(pdevPriv, &bufPtrs);
  1279.         while (!(pdevPriv->state & PDEV_REQ_EMPTY)) {
  1280.         if (pdevPriv->reqPtr->hdr.operation == PDEV_CLOSE) {
  1281.             /*
  1282.              * If we get a close message before the data are all read,
  1283.              * just allow the client to go away gracefully -- reply to
  1284.              * the close and get the h*** out of here.
  1285.              */
  1286.             Pdev_Reply    reply;
  1287.  
  1288.             reply.magic = PDEV_REPLY_MAGIC;
  1289.             reply.status = SUCCESS;
  1290.             reply.selectBits = 0;
  1291.             reply.replySize = 0;
  1292.             reply.replyBuf = (Address)NULL;
  1293.             reply.signal = 0;
  1294.             reply.code = 0;
  1295.             (void)Fs_IOControl(pdevPriv->streamID,
  1296.                        IOC_PDEV_REPLY,
  1297.                        sizeof(reply), (Address)&reply,
  1298.                        0, (Address)NULL);
  1299.             PdevRequestHandled(pdevPriv);
  1300.             goto done;
  1301.         }
  1302.         /*
  1303.          * Anything else we just drop on the floor
  1304.          */
  1305.         PdevRequestHandled(pdevPriv);
  1306.         }
  1307.     }
  1308.     } while (!pTimeOut || (pTimeOut->tv_sec || pTimeOut->tv_usec));
  1309.  
  1310. done:
  1311.     Bit_Free (selMask);
  1312. }
  1313.  
  1314. /*-
  1315.  *-----------------------------------------------------------------------
  1316.  * Pdev_EstablishNewConnections --
  1317.  *    Accept connections from new clients. 
  1318.  *
  1319.  * Results:
  1320.  *    None returned. pNewClients and *pNumNew are filled in.
  1321.  *
  1322.  * Side Effects:
  1323.  *    AllClientsMask and AllStreamsMask are altered. Fields in the
  1324.  *    private structure for the new clients are filled and several
  1325.  *    private structures are created.
  1326.  *
  1327.  *-----------------------------------------------------------------------
  1328.  */
  1329. void
  1330. Pdev_EstablishNewConnections (pNewClients, pNumNew)
  1331.     ClientPtr            *pNewClients;    /* Array to fill in */
  1332.     int                  *pNumNew;     /* Number of new connections
  1333.                      * established */
  1334. {
  1335.     Pdev_Notify          note;            /* Notification of new stream */
  1336.     PdevPrivPtr    pdevPriv;           /* New private information for us */
  1337.     ClntPrivPtr          pPriv;            /* New private information for client */
  1338.     ClientPtr          client;            /* New client */
  1339.     Pdev_Request    *pdevReq;       /* Pointer to current request */
  1340.     Pdev_Reply     openReply;          /* Reply to open request */
  1341.     Pdev_SetBufArgs    bufArgs;        /* Structure to set r/w buffers */
  1342.     int                  numBytes;       /* Number of bytes read */
  1343.     xConnClientPrefix    *xccp;            /* Client's description of itself */
  1344.     Boolean              swapped;        /* Set TRUE if client is byte-swapped.
  1345.                      * FALSE otherwise. */
  1346.     Boolean           writeBehind;    /* For IOC_PDEV_WRITE_BEHIND */
  1347.  
  1348.     pNewClients += *pNumNew;
  1349.     writeBehind = TRUE;            /* Turn on write-behind */
  1350.  
  1351.     while (1) {
  1352.     numBytes = read(Pdev_Conn, (char *) ¬e, sizeof(note));
  1353.     if ((numBytes != sizeof(note)) || (note.magic != PDEV_NOTIFY_MAGIC)) {
  1354.         return;
  1355.     }
  1356.  
  1357.     Ioc_SetBits(note.newStreamID, IOC_NON_BLOCKING);
  1358.     
  1359.     pdevPriv = (PdevPrivPtr) malloc(sizeof(PdevPrivRec));
  1360.     pdevPriv->streamID =                     note.newStreamID;
  1361.     pdevPriv->client =                      NullClient;
  1362.     pdevPriv->state =                       PDEV_REQ_EMPTY|PDEV_READ_EMPTY;
  1363.     pdevPriv->curPtrs.magic =               PDEV_BUF_PTR_MAGIC;
  1364.     pdevPriv->curPtrs.requestFirstByte =    -1;
  1365.     pdevPriv->curPtrs.requestLastByte =     -1;
  1366.     pdevPriv->curPtrs.readFirstByte =       -1;
  1367.     pdevPriv->curPtrs.readLastByte =        -1;
  1368.     pdevPriv->inPtr =                       (char *)NULL;
  1369.     pdevPriv->outPtr =                      pdevPriv->outBuf;
  1370.     pdevPriv->overflow =                    Buf_Init(0);
  1371.     pdevPriv->bigReq =                      (char *)NULL;
  1372.     pdevPriv->bigReqPtr =                    (char *)NULL;
  1373.  
  1374.     pPriv = (ClntPrivPtr) malloc(sizeof(ClntPrivRec));
  1375.     pPriv->readProc =                       PdevReadClient;
  1376.     pPriv->writeProc =                      PdevWriteClient;
  1377.     pPriv->closeProc =                      PdevCloseClient;
  1378.     pPriv->mask =                            (int *)0;
  1379.     pPriv->ready =                            (int *)0;
  1380.     pPriv->maskWidth =                      0;
  1381.     pPriv->devicePrivate =                     (pointer)pdevPriv;
  1382.     
  1383.     bufArgs.requestBufAddr = pdevPriv->inBuf;
  1384.     bufArgs.requestBufSize = IN_BUF_SIZE;
  1385.     bufArgs.readBufAddr = pdevPriv->outBuf;
  1386.     bufArgs.readBufSize = OUT_BUF_SIZE;
  1387.  
  1388.     (void)Fs_IOControl(pdevPriv->streamID, IOC_PDEV_SET_BUF,
  1389.                sizeof(bufArgs), (Address)&bufArgs,
  1390.                0, (Address)NULL);
  1391.     (void)Fs_IOControl(pdevPriv->streamID, IOC_PDEV_WRITE_BEHIND,
  1392.                sizeof(Boolean), (Address) &writeBehind,
  1393.                0, (Address)NULL);
  1394.  
  1395.     ExpandMasks (pPriv, pdevPriv->streamID);
  1396.  
  1397.     /*
  1398.      * Wait for and handle the OPEN request. If the request comes from
  1399.      * an un-authorized source, we return a status of FS_NO_ACCESS. If
  1400.      * there's an error, we close the stream and free everything.
  1401.      */
  1402.     if ((PdevWaitForReadable(pdevPriv, pPriv->ready) != 0) ||
  1403.         (pdevPriv->reqPtr->hdr.operation != PDEV_OPEN)) {
  1404.         (void) close(pdevPriv->streamID);
  1405.         free((char *)pdevPriv);
  1406.         free((char *)pPriv);
  1407.         continue;
  1408.     }
  1409. d223 2
  1410. a224 4
  1411.     if (InvalidHost(FamilySprite, pdevReq->param.open.uid,
  1412.             pdevReq->param.open.hostID)) {
  1413.         openReply.status = FS_NO_ACCESS;
  1414.         (void) Fs_IOControl(pdevPriv->streamID, IOC_PDEV_REPLY,
  1415. d227 1
  1416. a227 12
  1417.         
  1418.         (void) close(pdevPriv->streamID);
  1419.         free((char *)pdevPriv);
  1420.         free((char *)pPriv);
  1421.         continue;
  1422.     } else {
  1423.         openReply.status = SUCCESS;
  1424.         (void) Fs_IOControl(pdevPriv->streamID, IOC_PDEV_REPLY,
  1425.                 sizeof(openReply), (Address)&openReply,
  1426.                 0, (Address)NULL);
  1427.         
  1428.     }
  1429. d229 7
  1430. a235 104
  1431.     PdevRequestHandled(pdevPriv);
  1432.  
  1433.     /*
  1434.      * Once the OPEN operation has been received, we must wait for the
  1435.      * client to write an xConnClientPrefix on the device. Since the
  1436.      * Sprite Xlib doesn't pass any extra authorization string junk,
  1437.      * we only need to read the prefix.
  1438.      */
  1439.  
  1440.     if (PdevWaitForReadable(pdevPriv, pPriv->ready) != 0) {
  1441.         (void) close(pdevPriv->streamID);
  1442.         free((char *)pdevPriv);
  1443.         free((char *)pPriv);
  1444.         continue;
  1445.     }
  1446.     pdevReq = pdevPriv->reqPtr;
  1447.  
  1448.     if (pdevReq->hdr.operation == PDEV_WRITE_ASYNC) {
  1449.         pdevReq->hdr.operation = PDEV_WRITE;
  1450.     }
  1451.     if ((pdevReq->hdr.magic != PDEV_REQUEST_MAGIC) ||
  1452.         (pdevReq->hdr.operation != PDEV_WRITE) ||
  1453.         (pdevReq->hdr.requestSize < sizeof(xConnClientPrefix))) {
  1454.         (void) close(pdevPriv->streamID);
  1455.         free((char *)pdevPriv);
  1456.         free((char *)pPriv);
  1457.         continue;
  1458.     }
  1459.  
  1460.     xccp = (xConnClientPrefix *)&pdevReq[1];
  1461.     if (xccp->byteOrder != whichByteIsFirst) {
  1462.         SwapConnClientPrefix (xccp);
  1463.         swapped = TRUE;
  1464.     } else {
  1465.         swapped = FALSE;
  1466.     }
  1467.  
  1468.     if ((xccp->majorVersion != X_PROTOCOL) ||
  1469.         (xccp->minorVersion != X_PROTOCOL_REVISION)) {
  1470.         PdevRequestHandled(pdevPriv);
  1471.         PdevConnFail(pdevPriv, swapped, "Protocol version mismatch");
  1472.         (void) close(pdevPriv->streamID);
  1473.         free((char *)pdevPriv);
  1474.         free((char *)pPriv);
  1475.         continue;
  1476.     }
  1477.     if ((xccp->nbytesAuthProto != 0) || (xccp->nbytesAuthString != 0)) {
  1478.         PdevRequestHandled(pdevPriv);
  1479.         PdevConnFail(pdevPriv, swapped,
  1480.                 "Can't handle authorization strings");
  1481.         (void) close(pdevPriv->streamID);
  1482.         free((char *)pdevPriv);
  1483.         free((char *)pPriv);
  1484.         continue;
  1485.     }
  1486.  
  1487.     client = (ClientPtr)NextAvailableClient();
  1488.     if (client == NullClient) {
  1489.         PdevRequestHandled(pdevPriv);
  1490.         PdevConnFail(pdevPriv, swapped, "Too many clients");
  1491.         (void) close(pdevPriv->streamID);
  1492.         free((char *)pdevPriv);
  1493.         free((char *)pPriv);
  1494.         continue;
  1495.     } else {
  1496.         pdevPriv->client = client;
  1497.         client->osPrivate = (pointer)pPriv;
  1498.         client->swapped = swapped;
  1499.     }
  1500.     
  1501.     PdevRequestHandled(pdevPriv);
  1502.  
  1503.     if (DBG(PDEV) || DBG(CONN)) {
  1504.         ErrorF ("New Pdev connection: client %d (newID = %d)\n",
  1505.             client->index, pdevPriv->streamID);
  1506.     }
  1507.         
  1508.     if ((pdevPriv->state & PDEV_REQ_EMPTY) == 0) {
  1509.         /*
  1510.          * If there's still stuff left in the request buffer (beyond
  1511.          * the initial open request), mark the stream as having input...
  1512.          */
  1513.         Bit_Set(pdevPriv->streamID, ClientsWithInputMask);
  1514.     }
  1515.     
  1516.     *pNewClients = client;
  1517.     pNewClients++;
  1518.     (*pNumNew)++;
  1519.  
  1520.     /*
  1521.      * If we're only listening to one client, add the new client's
  1522.      * stream to the saved AllClients and AllStreams masks so it is
  1523.      * included when the grab is released. Otherwise, we can just
  1524.      * add the stream to the regular AllClients and AllStreams
  1525.      * masks.
  1526.      */
  1527.     if (GrabDone) {
  1528.         Bit_Set (pdevPriv->streamID, SavedAllClientsMask);
  1529.         Bit_Set (pdevPriv->streamID, SavedAllStreamsMask);
  1530.     } else {
  1531.         Bit_Set (pdevPriv->streamID, AllClientsMask);
  1532.         Bit_Set (pdevPriv->streamID, AllStreamsMask);
  1533.     }
  1534.     }
  1535. d240 3
  1536. a242 4
  1537.  * PdevCloseClient --
  1538.  *    Some client is being booted. Free up our part of its connection
  1539.  *    resources. XXX: Maybe we should wait for the read-ahead buffer to
  1540.  *    drain?
  1541. d245 1
  1542. a245 1
  1543.  *    None.
  1544. d255 3
  1545. a257 4
  1546. static void
  1547. PdevCloseClient (pPriv)
  1548.     ClntPrivPtr      pPriv;        /* Private data for client whose connection
  1549.                  * should be closed */
  1550. a259 1
  1551.     register int          streamID;
  1552. d261 9
  1553. a269 10
  1554.     pdevPriv = (PdevPrivPtr) pPriv->devicePrivate;
  1555.     
  1556.     streamID = pdevPriv->streamID;
  1557.     close(streamID);
  1558.     Bit_Clear(streamID, AllStreamsMask);
  1559.     Bit_Clear(streamID, SavedAllStreamsMask);
  1560.     Bit_Clear(streamID, AllClientsMask);
  1561.     Bit_Clear(streamID, SavedAllClientsMask);
  1562.     Bit_Clear(streamID, ClientsWithInputMask);
  1563.     Buf_Destroy(pdevPriv->overflow, TRUE);
  1564. d271 1
  1565. a271 4
  1566.     if (pdevPriv->state & PDEV_COLLECTING) {
  1567.     free((char *) pdevPriv->bigReq);
  1568.     }
  1569.         
  1570. d273 2
  1571. a276 3
  1572. #define request_length(req, cli) \
  1573.      (((cli)->swapped?lswaps(((xReq *)(req))->length):\
  1574.       ((xReq *)(req))->length) << 2)
  1575. d279 8
  1576. a286 12
  1577. /*-
  1578.  *-----------------------------------------------------------------------
  1579.  * PdevReadClient --
  1580.  *    Return one request from the given client. If the client is being
  1581.  *    naughty, we call ConnectionClosed to close the thing down.
  1582.  *    The client will be closed down as well if the stream which acted
  1583.  *    up was the only one open for the client. We still return NULL
  1584.  *    with status 0 from there, but the client is gone...
  1585.  *
  1586.  * Results:
  1587.  *    The request buffer.
  1588.  *
  1589. a287 1
  1590.  *    ClientsWithInputMask may be modified.
  1591. d292 5
  1592. a296 8
  1593. static char *
  1594. PdevReadClient (pPriv, pStatus, oldbuf)
  1595.     ClntPrivPtr          pPriv;        /* Client with input */
  1596.     int                  *pStatus;   /* Result of read:
  1597.                      *    >0 -- number of bytes in the request
  1598.                      *   0  -- not all the request is there
  1599.                      *    <0 -- indicates an error */
  1600.     char              *oldbuf;    /* The previous buffer */
  1601. a300 1
  1602.     xReq              *reqPtr;    /* Request to give back */
  1603. d305 25
  1604. a329 4
  1605.     pdevPriv = (PdevPrivPtr) pPriv->devicePrivate;
  1606.  
  1607.     Bit_Clear (pdevPriv->streamID, ClientsWithInputMask);
  1608.     
  1609. d331 17
  1610. a347 24
  1611.     if (Bit_IsSet(pdevPriv->streamID, pPriv->ready)) {
  1612.         /*
  1613.          * If the request buffer is empty, we think, then we need to see if
  1614.          * the kernel has anything for us. However, we only do the read on
  1615.          * the device if we actually got here because selecdt says the
  1616.          * stream is ready. This prevents a client from hogging the server
  1617.          * in an obnoxious fashion...
  1618.          */
  1619.         numBytes = read(pdevPriv->streamID, &bufPtrs, sizeof(bufPtrs));
  1620.         if (numBytes == -1) {
  1621.         if (errno != EWOULDBLOCK) {
  1622.             if (DBG(PDEV)) {
  1623.             Error("Reading buffer pointers");
  1624.             }
  1625.             *pStatus = -1;
  1626.             return((char *)NULL);
  1627.         } else {
  1628.             /*
  1629.              * Wasn't actually anything to read. Go on to
  1630.              * the next client...
  1631.              */
  1632.             *pStatus = 0;
  1633.             SchedYield();
  1634.             return ((char *)NULL);
  1635. d349 2
  1636. a350 9
  1637.         }
  1638.         if ((numBytes != sizeof(bufPtrs)) ||
  1639.         (bufPtrs.magic != PDEV_BUF_PTR_MAGIC)) {
  1640.             if (DBG(PDEV)) {
  1641.             ErrorF("Improper data when reading buffer pointers");
  1642.             }
  1643.             *pStatus = -1;
  1644.             return ((char *)NULL);
  1645.         }
  1646. a352 10
  1647.     if (pdevPriv->state & PDEV_REQ_EMPTY) {
  1648.         /*
  1649.          * If there are still no requests, there's nothing more to
  1650.          * be done. PdevSetPtrs will have copied any overflow
  1651.          * to the read-ahead buffer, so...
  1652.          */
  1653.         *pStatus = 0;
  1654.         SchedYield();
  1655.         return ((char *)NULL);
  1656.     }
  1657. d354 3
  1658. a356 7
  1659.  
  1660.     Bit_Clear (pdevPriv->streamID, pPriv->ready);
  1661.     
  1662.     /*
  1663.      * Process the requests until we get one that's a WRITE request,
  1664.      * then set inPtr to the data for the request and break out
  1665.      * of the loop.
  1666. d358 1
  1667. a358 3
  1668.     while ((pdevPriv->inPtr == (char *)NULL) &&
  1669.        !(pdevPriv->state & PDEV_REQ_EMPTY))
  1670.     {
  1671. d361 5
  1672. a365 4
  1673.         case PDEV_WRITE:
  1674.         if (DBG(PDEV)) {
  1675.             ErrorF("client %d: PDEV_WRITE(%d)\n",
  1676.                pdevPriv->client->index,
  1677. d369 10
  1678. d380 1
  1679. d386 2
  1680. a387 2
  1681.         if (DBG(PDEV) || DBG(CONN)) {
  1682.             ErrorF("client %d: PDEV_CLOSE\n", pdevPriv->client->index);
  1683. d401 2
  1684. a402 2
  1685.         *pStatus = -1;
  1686.         return ((char *)NULL);
  1687. d426 3
  1688. a428 3
  1689.         if (DBG(PDEV)) {
  1690.             ErrorF("client %d: PDEV_IOCTL(%x, %d, %x, %d, ...)\n",
  1691.                pdevPriv->client->index,
  1692. d455 2
  1693. a456 2
  1694.             if (DBG(PDEV)) {
  1695.                 ErrorF("Invalid IOCTL %x\n",
  1696. d488 2
  1697. a489 2
  1698.         if (DBG(PDEV)) {
  1699.             ErrorF("Bad new pdev request %d client %d\n",
  1700. d491 1
  1701. a491 1
  1702.                pdevPriv->client->index);
  1703. d498 2
  1704. a499 2
  1705.         *pStatus = -1;
  1706.         return ((char *)NULL);
  1707. d502 3
  1708. a504 147
  1709.     if (pdevPriv->inPtr == (char *)NULL) {
  1710.     /*
  1711.      * If didn't reach a PDEV_WRITE request, there's nothing more
  1712.      * to do...
  1713.      */
  1714.     Bit_Clear(pdevPriv->streamID, ClientsWithInputMask);
  1715.     SchedYield();
  1716.     *pStatus = 0;
  1717.     return ((char *)NULL);
  1718.     }
  1719.     
  1720.     if (pdevPriv->state & PDEV_COLLECTING) {
  1721.     /*
  1722.      * Collecting an X request that was broken across a WRITE boundary.
  1723.      * bigReqPtr points to the next place to store stuff for the
  1724.      * request, while need contains the number of bytes still needed
  1725.      * to fill the request. bigReq has been allocated to contain
  1726.      * the requisite space.
  1727.      */
  1728.     need = min(pdevPriv->need, pdevPriv->reqPtr->hdr.requestSize);
  1729.     bcopy(pdevPriv->inPtr, pdevPriv->bigReqPtr, need);
  1730.     pdevPriv->bigReqPtr += need;
  1731.     pdevPriv->need -= need;
  1732.     pdevPriv->inPtr += need;
  1733.     if (pdevPriv->need != 0) {
  1734.         PdevRequestHandled(pdevPriv);
  1735.         *pStatus = 0;
  1736.         return ((char *)NULL);
  1737.     } else {
  1738.         pdevPriv->reqPtr->hdr.requestSize -= need;
  1739.         need = request_length(pdevPriv->bigReq, pdevPriv->client);
  1740.         *pStatus = need;
  1741.         pdevPriv->state &= ~PDEV_COLLECTING;
  1742.         Bit_Set(pdevPriv->streamID, ClientsWithInputMask);
  1743.         if (DBG(PDEV)) {
  1744.         ErrorF("XRequest(%d, %d) #%d\n", pdevPriv->client->index,
  1745.                ((xReq *)pdevPriv->bigReq)->reqType,
  1746.                pdevPriv->client->sequence + 1);
  1747.         }
  1748.         return (pdevPriv->bigReq);
  1749.     }
  1750.     } else if (pdevPriv->state & PDEV_COLLECTING_HEADER) {
  1751.     /*
  1752.      * The header for the request was broken across a WRITE boundary.
  1753.      * bigReqPtr points to the place we left off in the header,
  1754.      * while bigReq points to a piece of memory big enough for
  1755.      * an xReq and no more.  Once the entire request header is seen,
  1756.      * we can allocate a large enough buffer for the entire request.
  1757.      */
  1758.     need = min(pdevPriv->need, pdevPriv->reqPtr->hdr.requestSize);
  1759.     bcopy(pdevPriv->inPtr, pdevPriv->bigReqPtr, need);
  1760.     pdevPriv->bigReqPtr += need;
  1761.     pdevPriv->need -= need;
  1762.     pdevPriv->inPtr += need;
  1763.     if (pdevPriv->need != 0) {
  1764.         /*
  1765.          * XXX: Shouldn't happen
  1766.          */
  1767.         PdevRequestHandled(pdevPriv);
  1768.         *pStatus = 0;
  1769.         return ((char *)NULL);
  1770.     } else {
  1771.         /*
  1772.          * We've now gotten a complete header. To keep this simple
  1773.          * we just allocate the needed buffer, copy the header in,
  1774.          * switch to COLLECTING state from COLLECTING_HEADER and
  1775.          * return a blocked read. We'll get called again (very
  1776.          * soon) to fill out the request...
  1777.          */
  1778.         xReq    *xreq;
  1779.  
  1780.         xreq = (xReq *)pdevPriv->bigReq;
  1781.         need = request_length(xreq, pdevPriv->client);
  1782.         pdevPriv->bigReq = malloc((unsigned) need);
  1783.         bcopy(xreq, pdevPriv->bigReq, sizeof(xReq));
  1784.         pdevPriv->bigReqPtr += sizeof(xReq);
  1785.         pdevPriv->need = need - sizeof(xReq);
  1786.         pdevPriv->state ^= PDEV_COLLECTING|PDEV_COLLECTING_HEADER;
  1787.         free((char *) xreq);
  1788.         *pStatus = 0;
  1789.         return ((char *)NULL);
  1790.     }
  1791.     }
  1792.     if (pdevPriv->bigReq != (char *)NULL) {
  1793.     /*
  1794.      * If we're not collecting anything and there's something
  1795.      * pointed to by bigReq, it must be old and should be
  1796.      * deallocated.
  1797.      */
  1798.     free((char *) pdevPriv->bigReq);
  1799.     pdevPriv->bigReq = (char *)NULL;
  1800.     }
  1801.     if (pdevPriv->reqPtr->hdr.requestSize < sizeof(xReq)) {
  1802.     if (pdevPriv->reqPtr->hdr.requestSize != 0) {
  1803.         /*
  1804.          * Only go into the COLLECTING_HEADER state if there are
  1805.          * data bytes left in the request (i.e. it's really a broken
  1806.          * header, not just an exhausted WRITE request).
  1807.          */
  1808.         pdevPriv->state |= PDEV_COLLECTING_HEADER;
  1809.         pdevPriv->bigReq = (char *) malloc(sizeof(xReq));
  1810.         bcopy(pdevPriv->inPtr, pdevPriv->bigReq,
  1811.             pdevPriv->reqPtr->hdr.requestSize);
  1812.         pdevPriv->bigReqPtr =
  1813.         pdevPriv->bigReq + pdevPriv->reqPtr->hdr.requestSize;
  1814.         pdevPriv->need = sizeof(xReq) - pdevPriv->reqPtr->hdr.requestSize;
  1815.     }
  1816.     PdevRequestHandled(pdevPriv);
  1817.     *pStatus = 0;
  1818.     return ((char *)NULL);
  1819.     } else {
  1820.     /*
  1821.      * Can actually figure out the size of the request. Store it
  1822.      * in 'need'
  1823.      */
  1824.     need = request_length (pdevPriv->inPtr, pdevPriv->client);
  1825.     
  1826.     if (need > pdevPriv->reqPtr->hdr.requestSize) {
  1827.         /*
  1828.          * The X request didn't fit in PDEV_WRITE request, so
  1829.          * we mark the stream as collecting a (big) request, copy
  1830.          * in whatever data we have and return a blocked read status.
  1831.          * Note we DO NOT yield the server since there may be another
  1832.          * write request pending.
  1833.          */
  1834.         pdevPriv->state |= PDEV_COLLECTING;
  1835.         pdevPriv->bigReq = (char *) malloc((unsigned) need);
  1836.         bcopy(pdevPriv->inPtr, pdevPriv->bigReq,
  1837.             pdevPriv->reqPtr->hdr.requestSize);
  1838.         pdevPriv->bigReqPtr =
  1839.         pdevPriv->bigReq + pdevPriv->reqPtr->hdr.requestSize;
  1840.         pdevPriv->need = need - pdevPriv->reqPtr->hdr.requestSize;
  1841.         PdevRequestHandled(pdevPriv);
  1842.         *pStatus = 0;
  1843.         return ((char *)NULL);
  1844.     } else {
  1845.         reqPtr = (xReq *)pdevPriv->inPtr;
  1846.         pdevPriv->inPtr += need;
  1847.         pdevPriv->reqPtr->hdr.requestSize -= need;
  1848.         *pStatus = need;
  1849.         Bit_Set(pdevPriv->streamID, ClientsWithInputMask);
  1850.         if (DBG(PDEV)) {
  1851.         ErrorF("XRequest(%d, %d) #%d\n", pdevPriv->client->index,
  1852.                reqPtr->reqType, pdevPriv->client->sequence+1);
  1853.         }
  1854.         return ((char *)reqPtr);
  1855.     }
  1856. d506 1
  1857. d511 1
  1858. a511 1
  1859.  * PdevWriteClient --
  1860. d513 1
  1861. a513 7
  1862.  *    as much as possible. Data that cannot fit in the read buffer are
  1863.  *    placed in the overflow buffer until the kernel catches up with us,
  1864.  *    at which point the data are copied back down to the read buffer.
  1865.  *    Output packets may be broken at arbitrary points and all
  1866.  *    transmissions are rounded to be a multiple of 32 bits long. Because
  1867.  *    of this, if the entire packet fits into the read buffer, the
  1868.  *    pad bytes do too.
  1869. d524 5
  1870. a528 5
  1871. static int
  1872. PdevWriteClient (pPriv, numBytes, xRepPtr)
  1873.     ClntPrivPtr      pPriv;        /* Client to receive the data */
  1874.     int              numBytes;     /* Number of bytes (unrounded) */
  1875.     Address          xRepPtr;     /* The data bytes */
  1876. a529 4
  1877.     int                      rndNumBytes;    /* Number of bytes, rounded to a
  1878.                          * longword */
  1879.     int                      pad = 0;        /* Padding bytes */
  1880.     register int          padding;        /* Number of bytes needed */
  1881. d532 2
  1882. d535 9
  1883. a543 1
  1884.     rndNumBytes = (numBytes + 3) & ~3;
  1885. d545 6
  1886. a550 4
  1887.     pdevPriv = (PdevPrivPtr) pPriv->devicePrivate;
  1888.     
  1889.     
  1890.     padding = rndNumBytes - numBytes;
  1891. d552 7
  1892. a558 13
  1893.     if (pdevPriv->curPtrs.readLastByte == (OUT_BUF_SIZE - 1)) {
  1894.     /*
  1895.      * Output buffer is full -- must copy data to overflow buffer
  1896.      */
  1897.     if (DBG(PDEV)) {
  1898.         ErrorF("WriteClient(%d): overflow -- ", pdevPriv->client->index);
  1899.     }
  1900.     Buf_AddBytes(pdevPriv->overflow, numBytes, (Byte *)xRepPtr);
  1901.     if (padding != 0) {
  1902.         Buf_AddBytes(pdevPriv->overflow, padding, (Byte *)&pad);
  1903.     }
  1904.     } else {
  1905.     int       numWrite;
  1906. d560 2
  1907. a561 3
  1908.     numWrite = min(numBytes,OUT_BUF_SIZE - pdevPriv->curPtrs.readLastByte);
  1909.     bcopy((char *) xRepPtr, (char *) pdevPriv->outPtr, numWrite);
  1910.     numBytes -= numWrite;
  1911. d570 95
  1912. a664 2
  1913.     
  1914.     if (numBytes != 0) {
  1915. d666 3
  1916. a668 2
  1917.          * Didn't manage to fit the entire request into the read-ahead
  1918.          * buffer. Copy excess to overflow.
  1919. d670 16
  1920. a685 18
  1921.         Buf_AddBytes(pdevPriv->overflow,
  1922.              numBytes,
  1923.              ((Byte *)xRepPtr) + numWrite);
  1924.         if (padding != 0) {
  1925.         Buf_AddBytes(pdevPriv->overflow,
  1926.                  padding,
  1927.                  (Byte *)&pad);
  1928.         }
  1929.     } else if (padding != 0) {
  1930.         /*
  1931.          * Because the buffer is a multiple of 32-bits long, any rounding
  1932.          * that needs to be done is guaranteed to fit if the unrounded
  1933.          * packet fit.
  1934.          */
  1935.         bcopy((char *) &pad, pdevPriv->outPtr, padding);
  1936.         pdevPriv->curPtrs.readLastByte += padding;
  1937.         pdevPriv->outPtr += padding;
  1938.     }
  1939. d688 3
  1940. a690 1
  1941.      * Inform kernel of new read buffer extents
  1942. d692 59
  1943. a750 8
  1944.     status = Fs_IOControl(pdevPriv->streamID, IOC_PDEV_SET_PTRS,
  1945.         sizeof(pdevPriv->curPtrs), (Address) &pdevPriv->curPtrs,
  1946.         0, (Address) NULL);
  1947.     if (status != 0) {
  1948.         errno = Compat_MapCode(status);
  1949.         if (DBG(PDEV)) {
  1950.         Error("WriteClient: SET_PTRS");
  1951.         }
  1952. d752 4
  1953. a755 54
  1954.     if (DBG(PDEV)) {
  1955.         ErrorF("WriteClient(%d): req %d:%d read %d:%d ",
  1956.            pdevPriv->client->index,
  1957.            pdevPriv->curPtrs.requestFirstByte,
  1958.            pdevPriv->curPtrs.requestLastByte,
  1959.            pdevPriv->curPtrs.readFirstByte,
  1960.            pdevPriv->curPtrs.readLastByte);
  1961.         
  1962.         switch (((xReply *)xRepPtr)->generic.type) {
  1963.         case X_Reply:
  1964.             ErrorF("Reply to %d\n",
  1965.                ((xReply *)xRepPtr)->generic.sequenceNumber);
  1966.             break;
  1967.         case X_Error:
  1968.             ErrorF("Error for %d\n",
  1969.                ((xReply *)xRepPtr)->generic.sequenceNumber);
  1970.             break;
  1971.         case KeyPress: ErrorF("KeyPress event\n"); break;
  1972.         case KeyRelease: ErrorF("KeyRelease event\n"); break;
  1973.         case ButtonPress: ErrorF("ButtonPress event\n"); break;
  1974.         case ButtonRelease: ErrorF("ButtonRelease event\n"); break;
  1975.         case MotionNotify: ErrorF("MotionNotify event\n"); break;
  1976.         case EnterNotify: ErrorF("EnterNotify event\n"); break;
  1977.         case LeaveNotify: ErrorF("LeaveNotify event\n"); break;
  1978.         case FocusIn: ErrorF("FocusIn event\n"); break;
  1979.         case FocusOut: ErrorF("FocusOut event\n"); break;
  1980.         case KeymapNotify: ErrorF("KeymapNotify event\n"); break;
  1981.         case Expose: ErrorF("Expose event\n"); break;
  1982.         case GraphicsExpose: ErrorF("GraphicsExpose event\n"); break;
  1983.         case NoExpose: ErrorF("NoExpose event\n"); break;
  1984.         case VisibilityNotify: ErrorF("VisibilityNotify event\n"); break;
  1985.         case CreateNotify: ErrorF("CreateNotify event\n"); break;
  1986.         case DestroyNotify: ErrorF("DestroyNotify event\n"); break;
  1987.         case UnmapNotify: ErrorF("UnmapNotify event\n"); break;
  1988.         case MapNotify: ErrorF("MapNotify event\n"); break;
  1989.         case MapRequest: ErrorF("MapRequest event\n"); break;
  1990.         case ReparentNotify: ErrorF("ReparentNotify event\n"); break;
  1991.         case ConfigureNotify: ErrorF("ConfigureNotify event\n"); break;
  1992.         case ConfigureRequest: ErrorF("ConfigureRequest event\n"); break;
  1993.         case GravityNotify: ErrorF("GravityNotify event\n"); break;
  1994.         case ResizeRequest: ErrorF("ResizeRequest event\n"); break;
  1995.         case CirculateNotify: ErrorF("CirculateNotify event\n"); break;
  1996.         case CirculateRequest: ErrorF("CirculateRequest event\n"); break;
  1997.         case PropertyNotify: ErrorF("PropertyNotify event\n"); break;
  1998.         case SelectionClear: ErrorF("SelectionClear event\n"); break;
  1999.         case SelectionRequest: ErrorF("SelectionRequest event\n"); break;
  2000.         case SelectionNotify: ErrorF("SelectionNotify event\n"); break;
  2001.         case ColormapNotify: ErrorF("ColormapNotify event\n"); break;
  2002.         case ClientMessage: ErrorF("ClientMessage event\n"); break;
  2003.         case MappingNotify: ErrorF("MappingNotify event\n"); break;
  2004.         default:
  2005.             ErrorF("Data\n");
  2006.         }
  2007.     }
  2008. a756 1
  2009.     return (numBytes);
  2010. d758 1
  2011. @
  2012.  
  2013.  
  2014. 1.11
  2015. log
  2016. @Added support for PDEV_WRITE_ASYNC
  2017. (whichis easy, because writes were already async)
  2018. @
  2019. text
  2020. @d2 2
  2021. a3 3
  2022.  * newpdev.c --
  2023.  *    Functions for handling a connection to a client over a new
  2024.  *    pseudo-device.
  2025. d6 1
  2026. a6 1
  2027.  *    which the client reads, and a 2K input buffer, to which it writes.
  2028. d40 1
  2029. a40 1
  2030. "$Header: /a/X/src/cmds/Xsprite/os/RCS/pdev.c,v 1.10 88/11/28 10:37:45 ouster Exp $ SPRITE (Berkeley)";
  2031. d489 2
  2032. d611 3
  2033. a613 1
  2034.     
  2035. d821 1
  2036. a821 1
  2037.     Pdev_Reply     reply;
  2038. d909 2
  2039. d925 2
  2040. a926 1
  2041.         int        replyBuf;
  2042. d953 1
  2043. a953 1
  2044.              * XXX: This should be handled by the
  2045. d977 8
  2046. d986 1
  2047. a986 1
  2048.                    IOC_PDEV_REPLY,
  2049. d1001 2
  2050. @
  2051.  
  2052.  
  2053. 1.10
  2054. log
  2055. @Changes for new pdev header format.
  2056. @
  2057. text
  2058. @d41 1
  2059. a41 1
  2060. "$Header: pdev.c,v 1.9 88/10/01 10:55:51 ouster Exp $ SPRITE (Berkeley)";
  2061. d647 3
  2062. d884 1
  2063. @
  2064.  
  2065.  
  2066. 1.9
  2067. log
  2068. @Change FS_NEW_MASTER => FS_PDEV_MASTER.
  2069. @
  2070. text
  2071. @d41 1
  2072. a41 1
  2073. "$Header: pdev.c,v 1.8 88/09/16 10:57:37 ouster Exp $ SPRITE (Berkeley)";
  2074. d291 1
  2075. a291 1
  2076.     pdevPriv->curPtrs.requestFirstByte += pdevPriv->reqPtr->messageSize;
  2077. d477 1
  2078. a477 1
  2079.         if (pdevPriv->reqPtr->operation == PDEV_CLOSE) {
  2080. d598 1
  2081. a598 1
  2082.         (pdevPriv->reqPtr->operation != PDEV_OPEN)) {
  2083. d647 3
  2084. a649 3
  2085.     if ((pdevReq->magic != PDEV_REQUEST_MAGIC) ||
  2086.         (pdevReq->operation != PDEV_WRITE) ||
  2087.         (pdevReq->requestSize < sizeof(xConnClientPrefix))) {
  2088. d880 1
  2089. a880 1
  2090.     switch (pdevPriv->reqPtr->operation) {
  2091. d885 1
  2092. a885 1
  2093.                pdevPriv->reqPtr->requestSize);
  2094. d926 1
  2095. a926 1
  2096.         if (pdevPriv->reqPtr->requestSize) {
  2097. d935 1
  2098. a935 1
  2099.                pdevPriv->reqPtr->requestSize,
  2100. d937 1
  2101. a937 1
  2102.                pdevPriv->reqPtr->replySize);
  2103. d985 1
  2104. a985 1
  2105.                pdevPriv->reqPtr->operation,
  2106. d1016 1
  2107. a1016 1
  2108.     need = min(pdevPriv->need, pdevPriv->reqPtr->requestSize);
  2109. d1026 1
  2110. a1026 1
  2111.         pdevPriv->reqPtr->requestSize -= need;
  2112. d1046 1
  2113. a1046 1
  2114.     need = min(pdevPriv->need, pdevPriv->reqPtr->requestSize);
  2115. d1089 2
  2116. a1090 2
  2117.     if (pdevPriv->reqPtr->requestSize < sizeof(xReq)) {
  2118.     if (pdevPriv->reqPtr->requestSize != 0) {
  2119. d1099 1
  2120. a1099 1
  2121.             pdevPriv->reqPtr->requestSize);
  2122. d1101 2
  2123. a1102 2
  2124.         pdevPriv->bigReq + pdevPriv->reqPtr->requestSize;
  2125.         pdevPriv->need = sizeof(xReq) - pdevPriv->reqPtr->requestSize;
  2126. d1114 1
  2127. a1114 1
  2128.     if (need > pdevPriv->reqPtr->requestSize) {
  2129. d1125 1
  2130. a1125 1
  2131.             pdevPriv->reqPtr->requestSize);
  2132. d1127 2
  2133. a1128 2
  2134.         pdevPriv->bigReq + pdevPriv->reqPtr->requestSize;
  2135.         pdevPriv->need = need - pdevPriv->reqPtr->requestSize;
  2136. d1135 1
  2137. a1135 1
  2138.         pdevPriv->reqPtr->requestSize -= need;
  2139. @
  2140.  
  2141.  
  2142. 1.8
  2143. log
  2144. @In changing to new C library goofed umask arguments.
  2145. @
  2146. text
  2147. @d41 1
  2148. a41 1
  2149. "$Header: pdev.c,v 1.7 88/09/11 13:09:20 ouster Exp $ SPRITE (Berkeley)";
  2150. d157 1
  2151. a157 1
  2152.         FS_NON_BLOCKING | FS_CREATE | FS_READ | FS_NEW_MASTER,
  2153. @
  2154.  
  2155.  
  2156. 1.7
  2157. log
  2158. @Typo in last mod.
  2159. @
  2160. text
  2161. @d41 1
  2162. a41 1
  2163. "$Header: pdev.c,v 1.6 88/09/11 13:01:04 ouster Exp $ SPRITE (Berkeley)";
  2164. d155 1
  2165. a155 1
  2166.     oldPermMask = umask(0777);
  2167. @
  2168.  
  2169.  
  2170. 1.6
  2171. log
  2172. @Switch to use errno for errors.
  2173. @
  2174. text
  2175. @d41 1
  2176. a41 1
  2177. "$Header: pdev.c,v 1.5 88/09/09 18:00:25 ouster Exp $ SPRITE (Berkeley)";
  2178. d160 1
  2179. a160 1
  2180.     errno = CompatMapCode(status);
  2181. d313 1
  2182. a313 1
  2183.     errno = CompatMapCode(status);
  2184. d1245 1
  2185. a1245 1
  2186.         errno = CompatMapCode(status);
  2187. @
  2188.  
  2189.  
  2190. 1.5
  2191. log
  2192. @Include bit.h.
  2193. @
  2194. text
  2195. @d41 1
  2196. a41 1
  2197. "$Header: pdev.c,v 1.4 88/09/08 18:15:52 ouster Exp $ SPRITE (Berkeley)";
  2198. d147 1
  2199. d156 8
  2200. a163 7
  2201.     if (Fs_Open (deviceName,
  2202.           FS_NON_BLOCKING | FS_CREATE | FS_READ | FS_NEW_MASTER,
  2203.           0666,
  2204.           &Pdev_Conn) != 0) {
  2205.               Error (deviceName);
  2206.               FatalError ("Could not open pseudo-device %s",
  2207.                   deviceName);
  2208. d288 2
  2209. d309 8
  2210. a316 8
  2211.     if (Fs_IOControl(pdevPriv->streamID, IOC_PDEV_SET_PTRS,
  2212.              sizeof(pdevPriv->curPtrs),
  2213.              (Address)&pdevPriv->curPtrs,
  2214.              0,
  2215.              (Address)NULL) != 0) {
  2216.              if (DBG(PDEV)) {
  2217.                  Error("RequestHandled: SET_PTRS");
  2218.              }
  2219. d1178 2
  2220. a1179 1
  2221.     register PdevPrivPtr pdevPriv;        /* Data private to client */
  2222. d1241 8
  2223. a1248 8
  2224.     if (Fs_IOControl(pdevPriv->streamID, IOC_PDEV_SET_PTRS,
  2225.              sizeof(pdevPriv->curPtrs),
  2226.              (Address)&pdevPriv->curPtrs,
  2227.              0,
  2228.              (Address)NULL) != 0) {
  2229.                  if (DBG(PDEV)) {
  2230.                  Error("WriteClient: SET_PTRS");
  2231.                  }
  2232. @
  2233.  
  2234.  
  2235. 1.4
  2236. log
  2237. @Intermediate check-in while converting to new C library.
  2238. @
  2239. text
  2240. @d41 1
  2241. a41 1
  2242. "$Header: pdev.c,v 1.3 88/08/26 16:13:09 brent Exp $ SPRITE (Berkeley)";
  2243. d61 1
  2244. @
  2245.  
  2246.  
  2247. 1.3
  2248. log
  2249. @Converted to new, standard, pseudo-device definitions
  2250. @
  2251. text
  2252. @d41 1
  2253. a41 1
  2254. "$Header: newpdev.c,v 1.1 87/11/29 19:51:59 deboor Exp $ SPRITE (Berkeley)";
  2255. d44 12
  2256. a57 2
  2257. #define NEED_REPLIES /* For Debugging Only */
  2258.  
  2259. d62 4
  2260. d69 1
  2261. a69 1
  2262.  * one of the Io_Print functions and expects two arguments: the name of the
  2263. d152 3
  2264. a154 3
  2265.     Io_PrintString (deviceName, DEVICE_TEMPLATE, hostname, display);
  2266.     if ((Fs_SetDefPerm (0777, &oldPermMask) != SUCCESS) ||
  2267.         (Fs_Open (deviceName,
  2268. d157 1
  2269. a157 1
  2270.           &Pdev_Conn) != SUCCESS)) {
  2271. d163 1
  2272. a163 1
  2273.     (void) Fs_SetDefPerm (oldPermMask, &oldPermMask);
  2274. d308 1
  2275. a308 1
  2276.              (Address)NULL) != SUCCESS) {
  2277. d326 2
  2278. a327 1
  2279.  *      SUCCESS or an error status.
  2280. d340 1
  2281. a340 1
  2282.     SpriteTime          timeout;    /* Timeout interval for select */
  2283. d345 2
  2284. a346 2
  2285.     timeout.seconds = REASONABLE_TIME;
  2286.     timeout.microseconds = 0;
  2287. d348 4
  2288. a351 8
  2289.     if ((Fs_Select (pdevPriv->streamID+1, &timeout, selMask, (int *)0, (int *)0,
  2290.            &numReady) != SUCCESS) ||
  2291.     (numReady != 1)) {
  2292.         if (numReady == 0) {
  2293.         return (FS_TIMEOUT);
  2294.         } else {
  2295.         return (stat_LastError);
  2296.         }
  2297. d353 7
  2298. a359 7
  2299.     
  2300.     if (Fs_Read(pdevPriv->streamID, sizeof(bufPtrs), &bufPtrs,
  2301.         &numBytes) != SUCCESS) {
  2302.             if (DBG(PDEV)) {
  2303.             Error ("PdevWaitForReadable");
  2304.             }
  2305.             return (FAILURE);
  2306. d365 1
  2307. a365 1
  2308.     return (FAILURE);
  2309. d368 1
  2310. a368 1
  2311.     return (SUCCESS);
  2312. d391 2
  2313. a392 2
  2314.     SpriteTime          timeout;        /* Timeout for select */
  2315.     SpriteTime          *pTimeOut;
  2316. d404 1
  2317. a404 1
  2318.     length = String_Length (reason);
  2319. d427 1
  2320. a427 1
  2321.     String_Copy(reason, (char *)&c[1]);
  2322. d432 1
  2323. a432 1
  2324.              0, (Address)NULL) != SUCCESS) {
  2325. d438 2
  2326. a439 2
  2327.     timeout.seconds = REASONABLE_TIME;
  2328.     timeout.microseconds = 0;
  2329. d441 1
  2330. a441 1
  2331.     pTimeOut = (SpriteTime *)0;
  2332. d453 7
  2333. a459 7
  2334.     if ((Fs_Select (pdevPriv->streamID+1, pTimeOut, selMask, (int *)0,
  2335.             (int *)0, &numReady) != SUCCESS) ||
  2336.         (numReady != 1)) {
  2337.         if (DBG(PDEV)) {
  2338.             ErrorF("PdevConnFail: didn't read in reasonable time\n");
  2339.         }
  2340.         break;
  2341. d461 5
  2342. a465 5
  2343.     if ((Fs_Read(pdevPriv->streamID, sizeof(bufPtrs),
  2344.              &bufPtrs, &numBytes) != SUCCESS) ||
  2345.         (numBytes != sizeof(bufPtrs)) ||
  2346.         (bufPtrs.magic != PDEV_BUF_PTR_MAGIC)) {
  2347.         break;
  2348. d498 1
  2349. a498 1
  2350.     } while (!pTimeOut || (pTimeOut->seconds || pTimeOut->microseconds));
  2351. d526 1
  2352. a526 1
  2353.     PdevPrivPtr    pdevPriv;       /* New private information for us */
  2354. d530 1
  2355. a530 1
  2356.     Pdev_Reply     openReply;      /* Reply to open request */
  2357. d542 3
  2358. a544 5
  2359.     if ((Fs_Read(Pdev_Conn, sizeof(note),
  2360.              (Address)¬e, &numBytes) != SUCCESS) ||
  2361.         (numBytes != sizeof(note)) ||
  2362.         (note.magic != PDEV_NOTIFY_MAGIC)) {
  2363.         return;
  2364. d546 1
  2365. a546 1
  2366.     
  2367. d549 1
  2368. a549 1
  2369.     pdevPriv = (PdevPrivPtr)Mem_Alloc(sizeof(PdevPrivRec));
  2370. d564 1
  2371. a564 1
  2372.     pPriv = (ClntPrivPtr)Mem_Alloc(sizeof(ClntPrivRec));
  2373. d592 1
  2374. a592 1
  2375.     if ((PdevWaitForReadable(pdevPriv, pPriv->ready) != SUCCESS) ||
  2376. d594 3
  2377. a596 3
  2378.         (void)Fs_Close(pdevPriv->streamID);
  2379.         Mem_Free((Address)pdevPriv);
  2380.         Mem_Free((Address)pPriv);
  2381. d613 3
  2382. a615 3
  2383.         (void)Fs_Close(pdevPriv->streamID);
  2384.         Mem_Free((Address)pdevPriv);
  2385.         Mem_Free((Address)pPriv);
  2386. d634 4
  2387. a637 4
  2388.     if (PdevWaitForReadable(pdevPriv, pPriv->ready) != SUCCESS) {
  2389.         (void)Fs_Close(pdevPriv->streamID);
  2390.         Mem_Free((Address)pdevPriv);
  2391.         Mem_Free((Address)pPriv);
  2392. d645 3
  2393. a647 3
  2394.         (void)Fs_Close(pdevPriv->streamID);
  2395.         Mem_Free((Address)pdevPriv);
  2396.         Mem_Free((Address)pPriv);
  2397. d663 3
  2398. a665 3
  2399.         (void)Fs_Close(pdevPriv->streamID);
  2400.         Mem_Free((Address)pdevPriv);
  2401.         Mem_Free((Address)pPriv);
  2402. d672 3
  2403. a674 3
  2404.         (void)Fs_Close(pdevPriv->streamID);
  2405.         Mem_Free((Address)pdevPriv);
  2406.         Mem_Free((Address)pPriv);
  2407. d682 3
  2408. a684 3
  2409.         (void)Fs_Close(pdevPriv->streamID);
  2410.         Mem_Free((Address)pdevPriv);
  2411.         Mem_Free((Address)pPriv);
  2412. d757 1
  2413. a757 1
  2414.     Fs_Close(streamID);
  2415. d766 1
  2416. a766 1
  2417.     Mem_Free(pdevPriv->bigReq);
  2418. d769 1
  2419. a769 1
  2420.     Mem_Free ((Address)pdevPriv);
  2421. d821 1
  2422. a821 1
  2423.          * the device if we actually got here because Fs_Select says the
  2424. d825 17
  2425. a841 17
  2426.         if (Fs_Read(pdevPriv->streamID, sizeof(bufPtrs),
  2427.             &bufPtrs, &numBytes) != SUCCESS) {
  2428.                 if (stat_LastError != FS_WOULD_BLOCK) {
  2429.                 if (DBG(PDEV)) {
  2430.                     Error("Reading buffer pointers");
  2431.                 }
  2432.                 *pStatus = -1;
  2433.                 return((char *)NULL);
  2434.                 } else {
  2435.                 /*
  2436.                  * Wasn't actually anything to read. Go on to
  2437.                  * the next client...
  2438.                  */
  2439.                 *pStatus = 0;
  2440.                 SchedYield();
  2441.                 return ((char *)NULL);
  2442.                 }
  2443. d1012 1
  2444. a1012 3
  2445.     Byte_Copy(need,
  2446.           pdevPriv->inPtr,
  2447.           pdevPriv->bigReqPtr);
  2448. d1042 1
  2449. a1042 3
  2450.     Byte_Copy(need,
  2451.           pdevPriv->inPtr,
  2452.           pdevPriv->bigReqPtr);
  2453. d1062 1
  2454. a1062 1
  2455.         
  2456. d1065 2
  2457. a1066 4
  2458.         pdevPriv->bigReq = Mem_Alloc(need);
  2459.         Byte_Copy(sizeof(xReq),
  2460.               xreq,
  2461.               pdevPriv->bigReq);
  2462. d1070 1
  2463. a1070 1
  2464.         Mem_Free((char *)xreq);
  2465. d1081 1
  2466. a1081 1
  2467.     Mem_Free(pdevPriv->bigReq);
  2468. d1092 3
  2469. a1094 4
  2470.         pdevPriv->bigReq = (char *)Mem_Alloc(sizeof(xReq));
  2471.         Byte_Copy(pdevPriv->reqPtr->requestSize,
  2472.               pdevPriv->inPtr,
  2473.               pdevPriv->bigReq);
  2474. d1118 3
  2475. a1120 4
  2476.         pdevPriv->bigReq = (char *)Mem_Alloc(need);
  2477.         Byte_Copy(pdevPriv->reqPtr->requestSize,
  2478.               pdevPriv->inPtr,
  2479.               pdevPriv->bigReq);
  2480. d1197 1
  2481. a1197 3
  2482.     Byte_Copy(numWrite,
  2483.           (Address)xRepPtr,
  2484.           pdevPriv->outPtr);
  2485. d1227 1
  2486. a1227 1
  2487.         Byte_Copy(padding, (char *) &pad, pdevPriv->outPtr);
  2488. d1239 1
  2489. a1239 1
  2490.              (Address)NULL) != SUCCESS) {
  2491. @
  2492.  
  2493.  
  2494. 1.2
  2495. log
  2496. @Fixes to go with the latest implementation of  pseudo-devices
  2497. @
  2498. text
  2499. @a38 2
  2500. #ifdef NEWPDEV
  2501.  
  2502. d84 1
  2503. a84 1
  2504.     Pdev_NewRequest    *reqPtr;    /* Address of next request to process */
  2505. d104 1
  2506. a104 1
  2507. } NewPdevPrivRec, *NewPdevPrivPtr;
  2508. d106 3
  2509. a108 3
  2510. static void       NewPdevCloseClient();
  2511. static char       *NewPdevReadClient();
  2512. static int        NewPdevWriteClient();
  2513. d110 1
  2514. a110 1
  2515. int              NewPdev_Conn;
  2516. d114 1
  2517. a114 1
  2518.  * NewPdev_Init --
  2519. d127 1
  2520. a127 1
  2521. NewPdev_Init(hostname)
  2522. d143 1
  2523. a143 1
  2524.           &NewPdev_Conn) != SUCCESS)) {
  2525. d154 1
  2526. a154 1
  2527.  * NewPdevSetPtrs --
  2528. d169 2
  2529. a170 2
  2530. NewPdevSetPtrs(pdevPriv, bufPtrs)
  2531.     NewPdevPrivPtr    pdevPriv;
  2532. d173 1
  2533. a173 1
  2534.     if (DBG(NEWPDEV)) {
  2535. d195 1
  2536. a195 1
  2537.         (Pdev_NewRequest *)&pdevPriv->inBuf[bufPtrs->requestFirstByte];
  2538. d243 1
  2539. a243 1
  2540.          * Need to make this -1 so NewPdevWriteClient works correctly
  2541. d254 1
  2542. a254 1
  2543.  * NewPdevRequestHandled --
  2544. d268 2
  2545. a269 2
  2546. NewPdevRequestHandled(pdevPriv)
  2547.     NewPdevPrivPtr    pdevPriv;
  2548. d274 1
  2549. a274 1
  2550.     (Pdev_NewRequest *)&pdevPriv->inBuf[pdevPriv->curPtrs.requestFirstByte];
  2551. d281 1
  2552. a281 1
  2553.     if (DBG(NEWPDEV)) {
  2554. d295 1
  2555. a295 1
  2556.              if (DBG(NEWPDEV)) {
  2557. d307 1
  2558. a307 1
  2559.  * NewPdevWaitForReadable --
  2560. d320 2
  2561. a321 2
  2562. NewPdevWaitForReadable (pdevPriv, selMask)
  2563.     NewPdevPrivPtr    pdevPriv;   /* Connection to read */
  2564. d345 2
  2565. a346 2
  2566.             if (DBG(NEWPDEV)) {
  2567.             Error ("NewPdevWaitForReadable");
  2568. d351 1
  2569. a351 1
  2570.     if (DBG(NEWPDEV)) {
  2571. d356 1
  2572. a356 1
  2573.     NewPdevSetPtrs(pdevPriv, &bufPtrs);
  2574. d362 1
  2575. a362 1
  2576.  * NewPdevConnFail --
  2577. d374 2
  2578. a375 2
  2579. NewPdevConnFail (pdevPriv, swapped, reason)
  2580.     NewPdevPrivPtr    pdevPriv;       /* Failed connection */
  2581. d429 1
  2582. a429 1
  2583.     if (DBG(NEWPDEV)) {
  2584. d445 2
  2585. a446 2
  2586.         if (DBG(NEWPDEV)) {
  2587.             ErrorF("NewPdevConnFail: didn't read in reasonable time\n");
  2588. d459 1
  2589. a459 1
  2590.         NewPdevSetPtrs(pdevPriv, &bufPtrs);
  2591. d467 1
  2592. a467 1
  2593.             Pdev_NewReply    reply;
  2594. d478 1
  2595. a478 1
  2596.             NewPdevRequestHandled(pdevPriv);
  2597. d484 1
  2598. a484 1
  2599.         NewPdevRequestHandled(pdevPriv);
  2600. d495 1
  2601. a495 1
  2602.  * NewPdev_EstablishNewConnections --
  2603. d509 1
  2604. a509 1
  2605. NewPdev_EstablishNewConnections (pNewClients, pNumNew)
  2606. d515 1
  2607. a515 1
  2608.     NewPdevPrivPtr    pdevPriv;       /* New private information for us */
  2609. d518 2
  2610. a519 2
  2611.     Pdev_NewRequest    *pdevReq;       /* Pointer to current request */
  2612.     Pdev_NewReply     openReply;      /* Reply to open request */
  2613. d531 1
  2614. a531 1
  2615.     if ((Fs_Read(NewPdev_Conn, sizeof(note),
  2616. d540 1
  2617. a540 1
  2618.     pdevPriv = (NewPdevPrivPtr)Mem_Alloc(sizeof(NewPdevPrivRec));
  2619. d556 3
  2620. a558 3
  2621.     pPriv->readProc =                       NewPdevReadClient;
  2622.     pPriv->writeProc =                      NewPdevWriteClient;
  2623.     pPriv->closeProc =                      NewPdevCloseClient;
  2624. d583 1
  2625. a583 1
  2626.     if ((NewPdevWaitForReadable(pdevPriv, pPriv->ready) != SUCCESS) ||
  2627. d616 1
  2628. a616 1
  2629.     NewPdevRequestHandled(pdevPriv);
  2630. d625 1
  2631. a625 1
  2632.     if (NewPdevWaitForReadable(pdevPriv, pPriv->ready) != SUCCESS) {
  2633. d652 2
  2634. a653 2
  2635.         NewPdevRequestHandled(pdevPriv);
  2636.         NewPdevConnFail(pdevPriv, swapped, "Protocol version mismatch");
  2637. d660 2
  2638. a661 2
  2639.         NewPdevRequestHandled(pdevPriv);
  2640.         NewPdevConnFail(pdevPriv, swapped,
  2641. d669 1
  2642. a669 1
  2643.     client = NextAvailableClient();
  2644. d671 2
  2645. a672 2
  2646.         NewPdevRequestHandled(pdevPriv);
  2647.         NewPdevConnFail(pdevPriv, swapped, "Too many clients");
  2648. d683 1
  2649. a683 1
  2650.     NewPdevRequestHandled(pdevPriv);
  2651. d685 2
  2652. a686 2
  2653.     if (DBG(NEWPDEV) || DBG(CONN)) {
  2654.         ErrorF ("New NewPdev connection: client %d (newID = %d)\n",
  2655. d721 1
  2656. a721 1
  2657.  * NewPdevCloseClient --
  2658. d738 1
  2659. a738 1
  2660. NewPdevCloseClient (pPriv)
  2661. d742 1
  2662. a742 1
  2663.     register NewPdevPrivPtr pdevPriv;
  2664. d745 1
  2665. a745 1
  2666.     pdevPriv = (NewPdevPrivPtr) pPriv->devicePrivate;
  2667. d770 1
  2668. a770 1
  2669.  * NewPdevReadClient --
  2670. d787 1
  2671. a787 1
  2672. NewPdevReadClient (pPriv, pStatus, oldbuf)
  2673. d795 1
  2674. a795 1
  2675.     NewPdevPrivPtr      pdevPriv;   /* Private data for the client */
  2676. d801 1
  2677. a801 1
  2678.     Pdev_NewReply     reply;
  2679. d803 1
  2680. a803 1
  2681.     pdevPriv = (NewPdevPrivPtr) pPriv->devicePrivate;
  2682. d819 1
  2683. a819 1
  2684.                 if (DBG(NEWPDEV)) {
  2685. d836 1
  2686. a836 1
  2687.             if (DBG(NEWPDEV)) {
  2688. d842 1
  2689. a842 1
  2690.         NewPdevSetPtrs(pdevPriv, &bufPtrs);
  2691. d847 1
  2692. a847 1
  2693.          * be done. NewPdevSetPtrs will have copied any overflow
  2694. d868 1
  2695. a868 1
  2696.         if (DBG(NEWPDEV)) {
  2697. d880 1
  2698. a880 1
  2699.         if (DBG(NEWPDEV) || DBG(CONN)) {
  2700. d892 1
  2701. a892 1
  2702.         NewPdevRequestHandled(pdevPriv);
  2703. d917 1
  2704. a917 1
  2705.         if (DBG(NEWPDEV)) {
  2706. d946 1
  2707. a946 1
  2708.             if (DBG(NEWPDEV)) {
  2709. d957 1
  2710. a957 1
  2711.         NewPdevRequestHandled(pdevPriv);
  2712. d969 1
  2713. a969 1
  2714.         if (DBG(NEWPDEV)) {
  2715. d978 1
  2716. a978 1
  2717.         NewPdevRequestHandled(pdevPriv);
  2718. d1010 1
  2719. a1010 1
  2720.         NewPdevRequestHandled(pdevPriv);
  2721. d1019 1
  2722. a1019 1
  2723.         if (DBG(NEWPDEV)) {
  2724. d1045 1
  2725. a1045 1
  2726.         NewPdevRequestHandled(pdevPriv);
  2727. d1097 1
  2728. a1097 1
  2729.     NewPdevRequestHandled(pdevPriv);
  2730. d1123 1
  2731. a1123 1
  2732.         NewPdevRequestHandled(pdevPriv);
  2733. d1132 1
  2734. a1132 1
  2735.         if (DBG(NEWPDEV)) {
  2736. d1143 1
  2737. a1143 1
  2738.  * NewPdevWriteClient --
  2739. d1163 1
  2740. a1163 1
  2741. NewPdevWriteClient (pPriv, numBytes, xRepPtr)
  2742. d1172 1
  2743. a1172 1
  2744.     register NewPdevPrivPtr pdevPriv;        /* Data private to client */
  2745. d1176 1
  2746. a1176 1
  2747.     pdevPriv = (NewPdevPrivPtr) pPriv->devicePrivate;
  2748. d1185 1
  2749. a1185 1
  2750.     if (DBG(NEWPDEV)) {
  2751. d1241 1
  2752. a1241 1
  2753.                  if (DBG(NEWPDEV)) {
  2754. d1245 1
  2755. a1245 1
  2756.     if (DBG(NEWPDEV)) {
  2757. a1301 2
  2758.  
  2759. #endif NEWPDEV
  2760. @
  2761.  
  2762.  
  2763. 1.1
  2764. log
  2765. @Initial revision
  2766. @
  2767. text
  2768. @d39 2
  2769. d43 1
  2770. a43 1
  2771. "$Header: pdev.c,v 1.1 87/11/01 20:17:30 deboor Exp $ SPRITE (Berkeley)";
  2772. d60 1
  2773. a60 1
  2774. #define    DEVICE_TEMPLATE    "/hosts/%s/X1%s"
  2775. d335 1
  2776. a335 1
  2777.     if ((Fs_Select (pdevPriv->streamID+1, /*&timeout*/ (SpriteTime *)0, selMask, (int *)0, (int *)0,
  2778. d462 26
  2779. d489 1
  2780. a489 1
  2781.     } while (1);
  2782. d491 1
  2783. d527 1
  2784. d530 1
  2785. d574 3
  2786. d654 1
  2787. d662 1
  2788. d673 1
  2789. d1304 2
  2790. @
  2791.